2017-06-27 65 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