我们有两个类(一个父类和一个子类)。两者都使用私有变量来存储值,但父级不应该提供setter(x和y是用构造函数给出的,它们是某种不可变的)。 B应该用x和y的setter扩展A.有没有一种常用的方法呢?
class A{
private int x;
private int y;
A(int x, int y){
this.x = x;
this.y = y;
}
}
class B extends A{
public void setx(int x){
this.x = x;
}
//same for y
}
一些想法
答案 0 :(得分:3)
在基类中将变量声明为protected
,并在子类中编写getter和setter。
答案 1 :(得分:3)
如果您希望变量是不可变的,那么它应该是
class B extends A{
public B(int x, int y){
super(x, y);
}
}
目前,A中的x和y变量不是不可变的。为了使它们不可变,然后在final
这是你可以分配x和y的唯一方法,因为它们是私有的。如果你想要setter那么你必须保护变量。
就个人而言,我是不变的忠实粉丝,所以这样做而不是制定者 - 创造物品通常很便宜。
答案 2 :(得分:1)
你不能拥有一个私有成员变量,也没有方法(这里有方法,我的意思也就是构造函数)设置它(好吧,技术上你可以,但它没有意义)。如果希望变量可以从派生类中设置,则必须对它们进行保护。
编辑:但是,您可以在基类中定义受保护的“帮助程序”setter,并从派生类中的公共setter调用此受保护的帮助程序setter。
第二编辑:另一种可能性是在基类中定义一个抽象的getter,并在派生类(模板模式)中实现getter,setter以及私有字段。
答案 3 :(得分:0)
这是一个奇怪的问题,不可改变但是可变,私密但公开......正确的方法应该是让它们受到保护,正如大家所说的那样。
无论如何,在java中你可以使用脏技巧,如果安全管理员不抱怨,请查看:
import java.lang.reflect.Field;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Priv
{
public static class A
{
private final int x;
public A(int x)
{
this.x = x;
}
}
public static class B extends A
{
public B(int x)
{
super(x);
}
public void setX(int x)
{
Class c = A.class;
try
{
Field f = c.getDeclaredField("x");
f.setAccessible(true);
f.set(this, x);
} catch (IllegalArgumentException ex) {
Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchFieldException ex) {
Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
}
}
public int getX()
{
int v = 0;
try {
Class c = A.class;
Field f = c.getDeclaredField("x");
f.setAccessible(true);
v = f.getInt(this);
} catch (IllegalArgumentException ex) {
Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchFieldException ex) {
Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
}
return v;
}
}
public static void main(String[] args)
{
B b = new B(5);
System.out.println("b.x is " + b.getX());
b.setX(42);
System.out.println("b.x now is " + b.getX());
}
}
答案 4 :(得分:0)
没有不可变的概念你是否有任何setter方法或子类的构造函数调用super来重新初始化私有的超类变量。
immutable本质上是线程安全的。