1
類A從抽象類B派生並實現了抽象方法foo。 現在在foo方法中,我想要做一些依賴於類A的成員變量mType的東西。然而,這會導致一個bug,因爲在抽象類B的構造函數中調用foo,因此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 {
// ...
}
}
}
[永遠不要從構造函數調用覆蓋方法](http://stackoverflow.com/questions/3404301/whats-wrong-with-overridable-method-calls-in-constructors)。 – Seelenvirtuose 2014-09-25 08:28:16
您可以在構造函數中的'foo()'中執行任何設置代碼?爲什麼重寫它,如果你只是立即調用它呢? – 2014-09-25 08:29:10
在構造函數中調用可重寫方法的錯誤做法,但是如果您必須*,您可以更改'foo'的簽名以獲取'foo(Type)'並執行所需的任何操作,即分配您的成員並執行其他檢查等等 – webuster 2014-09-25 08:54:55