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 {
// ...
}
}
}
答案 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方法可以解决这个问题。