2017-10-10 26 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); 
    } 
} 
相關問題