2017-06-27 64 views
0

在類的注入構造函數中,我必須使用適當的參數調用超級構造函數。 super應該通過多態來調用子類的方法(我有來自實現相同方法的同一個父類的多個子類)。 問題是子類中的方法依賴於已經注入了成員變量。我的例子中的子類依賴於不同類型的多個變量。 此外,父類是某些庫中的本地類,我無法更改。 參見下面的示例性的,非常簡化的,代碼:在注入構造函數之前注入成員變量

public class A { 

    @Inject 
    public A(SomeType t) 
    { 
     workon(t1); 
    } 
} 


public class B extends A{ 

    @Inject 
    private MemberType mt; 

    @Inject 
    public B(SomeType t) 
    { 
     super(t) 
    } 

    public void workOn(SomeType t) 
    { 
     // mt is not set yet since this method 
     // is called from the super constructor! 
     mt.setT(t); 
    } 
} 

有一種方法調用比手動對其進行初始化以外的繼承的方法之前注入成員變量?

+2

爲了構造B的一個實例,你需要相同的實例。好吧,它聞起來像一個設計缺陷。 – Juvanis

回答

1

注入的MemberType實例進入A明確的構造函數:

interface Workon { 
    public void workon(SomeType t); 
} 

class MemberType implements Workon { 
    public void workon(SomeType t) { 
     this.setT(t);   
    } 
} 

class A { 
    @Inject 
    public A(SomeType t, Workon w) { 
     w.workon(t); 
    } 
} 

class B extends A { 
    private final MemberType mt; 

    @Inject 
    public B(SomeType t, MemberType mt) { 
     super(t, mt); 
     this.mt = mt; 
    } 
} 

一般來說,構造函數注入是你的朋友。如果一個類需要一個的東西,通常最好在構造函數中明確要求東西,因爲那樣你就知道它在需要時已經準備好了。這有時需要提出新類型的東西。

在這種情況下,workon方法的特定行爲會更改構造函數A的行爲;即它是A的構造函數行爲的參數,所以只需將其作爲實際參數即可。


如果你不能改變的A構造,並假設A沒有明確依賴於workon的結果,你也可以從B調用實際執行workon()當它是可能的:

class B extends A { 
    SomeType t; 
    MemberType t; 

    public B (SomeType t) { 
     super(t); 
     this.t = t; 
    } 

    public void workon(SomeType t) { 
     // do nothing here 
    } 

    // should get called after the object is fully constructed 
    @Inject 
    public void setMt(MemberType mt) { 
     this.mt = mt; 
     // what workon() did 
     mt.setT(t); 
    } 
} 
+0

這當然是一種解決方案,但是我有不同的要求,我不能改變超級構造函數(上面的例子只是一個簡化) – AHH

+0

不能改變(可以破解的)構造函數是一個相當重要的要求,你應該在你的問題中提及這一點。 – millimoose

+0

@AHH - 給了它另一個去,第二個解決方案是否仍然可以取決於你的案件的一些細節,但是被省略了。 – millimoose