6

考虑到那个不起作用的简单java代码:

public class Bar extends AbstractBar{

    private final Foo foo = new Foo(bar);

    public Bar(){
        super(foo);
    }
}

我需要在调用之前创建一个对象,super()因为我需要在母类中推送它。

我不想使用初始化块,也不想做类似的事情:

super(new Foo(bar))在我的构造函数中..

如何在超级呼叫之前将数据发送到母班?

4

3 回答 3

17

如果Foo必须存储在字段中,您可以这样做:

public class Bar extends AbstractBar{    
    private final Foo foo;

    private Bar(Foo foo) {
        super(foo);
        this.foo = foo;
    }

    public Bar(){
        this(new Foo(bar));
    }
}

否则super(new Foo(bar))对我来说看起来很合法,如果你愿意,你可以包装new Foo(bar)成一个static方法。

另请注意,字段初始化程序(如您的示例中所示)和初始化程序块也无济于事,因为它们在超类构造函数之后运行。如果将字段声明为final您的示例将无法编译,否则您将进入null超类构造函数。

于 2012-06-19T15:38:16.390 回答
1

这在java中是不可能的。唯一可能的解决方案是超级构造函数中的新调用。

如果 foo 对象可以在实例之间共享,您可以将其声明为静态

public class Bar extends AbstractBar{

    private static final Foo foo = new Foo(bar);

    public Bar(){
        super(foo);
    }
}

如果超类在您的控制之下,您可以重构它并使用模板方法模式将对象拉入构造函数,而不是从子类中提取它。这适用于好莱坞原则:不要打电话给我们,我们会打电话给你;)

public abstract class AbstractBar{

    private Object thing;

    public AbstractBar(){
         this.thing = this.createThatThing();            
    }

    protected abstract Object createThatThing();
}

public class Bar extends AbstractBar {

     // no constructor needed

     protected Object createThatThing(){
          return new Thing();
     }
}
于 2012-06-19T15:37:43.493 回答
1
class AbstractBar{
    public AbstractBar() {
    }
    public AbstractBar(Foo t) {
    }
}
class Bar extends AbstractBar{
    static Foo t=null;
    public Bar() {
        super(t=new Foo());
    }
}
class Foo{...}
于 2012-06-19T15:44:15.450 回答