调用基类构造函数之前的Init成员变量

时间:2014-09-25 08:23:50

标签: java

A类派生自抽象类B并实现抽象方法foo。 现在在方法foo中我想做一些依赖于类A的成员变量mType的东西。然而,这会导致错误,因为foo是在抽象类B的构造函数中调用的,因此mType尚未初始化。

不可能在super()之前初始化mType,所以我不知道一个好的和干净的方法来解决这个问题。当然我可以让mType成为B的成员,但我认为这不是一个很好的方法,因为mType与这个类没什么关系,在这个例子中这可能不太清楚,但当然为了解释这个问题,我已经将实际情况重写为一个简单的简单问题。

解决这个问题的好方法是什么?

public abstract class B {
    public B() { 
        foo(); // A::mType IS NOT INITIALISED!!
    }

    protected abstract void foo();
}

private class A extends B {
    public enum Type { TYPE1, TYPE2 };

    public A(Type aType) {
        super();
        mType = aType;
    }

    @Override
    protected void foo() {
        if (mType == Type.TYPE1) {
            // ..
        } else {
            // ...
        }
    }
}

1 个答案:

答案 0 :(得分:0)

同意Seelenvirtuose的评论,我将回答我的问题。在构造函数中调用可覆盖的方法确实是不好的做法。以下解决了这个问题:

public abstract class B {
    public B() { }

    protected abstract void foo();

    protected void init() {
        foo();
    }
}

private class A extends B {
    public enum Type { TYPE1, TYPE2 };

    public A(Type aType) {
        super();
        mType = aType;
        init();
    }

    @Override
    protected void foo() {
        if (mType == Type.TYPE1) {
            // ..
        } else {
            // ...
        }
    }
}
乍一看,它可能看起来似乎不切实际,为什么不简单地在A类的构造函数中调用foo。但是在我的实际情况中它更复杂,需要以特定顺序调用各种重写方法。基类需要为此提供一种方法,以避免代码重复。添加一个从派生类调用的简单init方法可以解决这个问题。

相关问题