簡體   English   中英

在構造函數中使用重寫方法的替代方法,Java

[英]Alternatives to using overridden methods in constructors, Java

在我編寫的Java項目中,我最終使用了在構造函數中重寫的方法。 就像是:

class SuperClass {
    SuperClass() {
        intialise();
    }

    protected void initialise() {
        //Do some stuff common to all subclasses
        methodA();
        methodB();
    }

    protected abstract void methodA();

    protected abstract void methodB();
}

class SubClass1() {
    SubClass() {
        super();
    }
    protected void methodA() { //Do something }
    protected void methodB() { //Do something }

}

class SubClass2() {
    SubClass() {
        super();
    }
    protected void methodA() { //Do something else }
    protected void methodB() { //Do something else}

}

我現在意識到,雖然在我的情況下它工作正常,但是有點危險,因為SubClass方法在一個目前只被構造為SuperClass對象的對象上調用(當擴展SuperClass的新類被添加時,可能會忽略這一點)未來)。 由於對象的創建方式不同,它在c ++中也不起作用。

我能想到的唯一方法就是將initialise方法調用向下移動到具體的類構造函數:

   class SuperClass {
    SuperClass() {            
    }

    protected void initialise() {
        methodA();
        methodB();
    }

    protected abstract void methodA();

    protected abstract void methodB();
}

class SubClass1() {
    SubClass() {
        super();
        initialise();
    }
    protected void methodA() { //Do something }
    protected void methodB() { //Do something }

}...

這是解決這個問題的常用方法嗎? 擴展SuperClass的所有其他類需要記住調用initialise()似乎是一種恥辱(並且容易忘記)。

我還發現自己在更復雜的情境中做了類似的事情,它在構造函數中使用了Factory方法,在子類中重寫它以決定實現哪個具體類。 我能想到的唯一另一種方法是將這種設計模式保持原樣,或許可以構建一個兩階段的過程; 即用最小的構造,然后調用第二種方法來完成工作。

需要初始化的對象實際上需要通過工廠方法創建。 你確實提到了一個工廠,但是從構造函數中調用,所以這聽起來也不像是簡單的方法。 如果你只是在基類中有一個工廠,公共不可見的構造函數,以及一個決定返回哪個具體類的機制,那么工廠將很容易地執行初始化策略。

這實際上不是一個好主意,因為當調用其methodA()和methodB()時,您的子類將無法正確構造。 對於擴展課程的人來說,這將是非常混亂的。 建議您使用抽象的init() ,如dlev在他/她的評論中所建議的那樣。

我想知道你是否讓事情變得比他們需要的更復雜。

在您的示例中,methodA的每個實現所完成的工作可以移動到執行該實現的類的構造函數中。 因此,不要使用SubClass :: methodA,只需將邏輯移動到SubClass構造函數中。

如果你這樣做,你可以獲得清晰,代價是可能難以理解對各種初始化位執行順序的控制。

Bruce Eckel在他的“Thinking in Java”中提出的建議是使你的methodA()和類SuperClass的方法B()最終或私有(隱式最終),因此它們可以從超類構造函數訪問,盡管沒有派生類會有訪問這些方法,因此,不會有任何危險的覆蓋 - 任何派生類中聲明的類似簽名的任何方法都只是新方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM