2017-10-10 46 views
2

根据this question的回答,考虑到我有一个在声明中初始化字段的类,当我扩展该类并需要子类具有不同的默认值时,我应该怎么做?当子类在构造函数中初始化时,我应该在超类的声明中保持字段初始化吗?

我应该在子类的构造函数分配新的默认值,并保持在该声明的超?:

public class Bird { 
    private boolean flight = true; 
} 

public class Penguin extends Bird { 
    public Penguin() { 
     flight = false; 
    } 
} 

或者我应该重构,使这两个类初始化在构造函数中的字段赋值?

this question的答案看来,没有显着的技术差异,所以这是一个关于语义的问题。

+2

目前,该代码甚至无法编译,因为'企鹅'无法访问'鸟'。就我个人而言,我会在'Bird'中提供一个受保护的构造函数,让子类为'flight'提供一个值 - 这样您就可以保持字段的私有性并使其成为最终的。 –

+0

航班是私立的儿童班。 – Optional

+1

尽管存在可见性问题,它会将此视为基于意见。就个人而言,我优先在父'Bird'中定义一般/默认值。但是所有的孩子都会用自己需要的价值来重写他们。因此,如果我或其他人忘记在孩子中设置一个值,那么父母中的值只是作为默认值或回退值存在。 – Korashen

回答

2

首先在两种情况之间的差异。

对于不变财产(最严格的 - 不错 - 的情况下):

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 

坐在另一边,在班级飞行。

1

如果你设计的扩展超并要允许某些领域是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); 
    } 
} 
相关问题