簡體   English   中英

Java,隱式調用重寫方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM