当子类在构造函数中初始化时,我应该在超类的声明中保持字段初始化吗?
问题描述:
根据this question的回答,考虑到我有一个在声明中初始化字段的类,当我扩展该类并需要子类具有不同的默认值时,我应该怎么做?当子类在构造函数中初始化时,我应该在超类的声明中保持字段初始化吗?
我应该在子类的构造函数分配新的默认值,并保持在该声明的超?:
public class Bird {
private boolean flight = true;
}
public class Penguin extends Bird {
public Penguin() {
flight = false;
}
}
或者我应该重构,使这两个类初始化在构造函数中的字段赋值?
从this question的答案看来,没有显着的技术差异,所以这是一个关于语义的问题。
答
首先在两种情况之间的差异。
对于不变财产(最严格的 - 不错 - 的情况下):
public class Bird {
public final boolean flight;
public Bird() {
this(true);
}
protected Bird(boolean flight) {
this.flight = flight();
}
}
public class Penguin extends Bird {
public Penguin() {
super(false);
}
}
对于一个更*,动态使用:
public class Bird {
protected boolean flight = true;
public boolean hasFligth() {
return flight;
}
}
public class Penguin extends Bird {
public Penguin() {
flight = false;
}
}
然而flight
可能被认为不是一个属性在每个鸟类/企鹅的物体上:它是这个类的一个属性(企鹅,鸵鸟,...)。一种策略模式,或者:
Map<Class<Bird>, Boolean>
Set<Class<Bird>> // better
坐在另一边,在班级飞行。
答
如果你设计的扩展超并要允许某些领域是initializable另一个值,你应该通过构造函数参数暴露这样的:
public class Bird {
private final boolean flight = true;
public Bird() {
this(true);
}
public Bird(boolean flight) {
this.fligjt = flight;
}
public boolean isFlight() {
return this.flight;
}
}
public class Penguin extends Bird {
public Penguin() {
super(false);
}
}
目前,该代码甚至无法编译,因为'企鹅'无法访问'鸟'。就我个人而言,我会在'Bird'中提供一个受保护的构造函数,让子类为'flight'提供一个值 - 这样您就可以保持字段的私有性并使其成为最终的。 –
航班是私立的儿童班。 – Optional
尽管存在可见性问题,它会将此视为基于意见。就个人而言,我优先在父'Bird'中定义一般/默认值。但是所有的孩子都会用自己需要的价值来重写他们。因此,如果我或其他人忘记在孩子中设置一个值,那么父母中的值只是作为默认值或回退值存在。 – Korashen