[英]Java, Call overridden method implicitly
現在在一些Java代碼中,我有類似的東西
class A {
void f() {
}
A() {
f();
}
}
class B extends A{
@Override
void f() {
//do some stuff
super.f();
}
}
class C extends B {
@Override
void f() {
//do some stuff
super.f();
}
}
我希望調用f()
然后向上遍歷每個父類,運行重寫的f()
。 我通過顯式調用super.f()
來做到這一點,盡管我不想這樣做。
我這樣做的原因是必須在到達A中的構造函數之后進行后處理。 並且每個類中都有狀態正確初始化,這就是為什么我們有f()
的向上軌跡。
所以A
的構造函數確實如此
A() {
//init some state in a
f(); //run f(), which will depend on the previous operation
}
如果我做new C();
我想要調用Cf()
,然后調用Bf()
,然后調用Af()
無論如何,如果有更聰明的方法,我會接受它。
在構造函數中調用非final方法通常是一個壞主意 - 至少,我建議你大量記錄它。 請記住,當調用f()時,不會調用C的構造函數 - 也不會調用任何變量初始值設定項。 該對象只是半初始化,因此需要非常仔細地編寫方法。
雖然在普通的Java中沒有辦法隱式調用super.f()
。 鑒於我將圍繞該代碼發出大量警告,單一聲明遠離世界末日:)
如果你想驗證它是否被調用,你可以在調用后立即檢查A的構造函數中的Af()
結果 - 這將檢查調用是否已達到頂級。
這可能對你有所幫助 - 這是一種強制子類調用super的方法; 這將幫助您檢測開發人員錯誤,其中子類的實現者忘記繼續調用鏈到super.f():
class A {
boolean fDone;
public final void f() {
fDone = false;
doF();
if (!fDone) {
throw new IllegalStateException("super.f() was not called");
}
}
protected void doF() {
//do some operation
fDone = true;
}
}
class B extends A {
protected void doF() {
//some operation, maybe repeat this pattern of using a flag to enforce super call
super.doF();
}
}
所以,孩子會覆蓋doF(),但是需要調用super.doF();
據我所知,沒有辦法做到這一點。 AspectJ可能會做類似的事情,但是我想你必須用注釋來標記它,這比調用super.f()
少得多。 您需要表示正在調用超類方法,因為您需要能夠單獨為每個子類做出決定 - 否則,您可能有一個子類根本不想將任何內容委托給超類 - 所以默認是您只需輸入代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.