2011-05-23 49 views
6

如果我有一個類中的方法public void send() {//some code}並且擁有這個類的子對象,也有一個方法public void send() {//some code},我如何確保孩子必須在send()方法的某處調用super.send() ?如何確保在孩子中使用超級方法?

我在想這件事,因爲我寫過API,如果在重寫它時沒有調用超類方法,它會拋出一個異常告訴我我沒有調用超類方法。這是硬編碼還是可以用Java中的一些關鍵字來完成?

回答

14

你真的不能,但你可以...

class MySuperClass { 
    public final void send() { 
     preSend(); 
     // do the work... 
     postSend(); 
    } 

    protected void preSend() { 
     // to be overridden in by sub classes 
    } 

    protected void postSend() { 
     // to be overridden in by sub classes 
    } 

} 
+0

這對大多數人來說可能更好。但是,您可以使用標誌在運行時強制調用(但沒有編譯時間捕獲)。 – 2011-05-23 04:12:44

+0

我會使preSend()和postSend()爲虛擬。這是因爲如果對象實例化爲: MySuperClass * obj = new ClassDerivedFromMySuperClass(); 這是非常經常使用的方法(例如對於插件),並且不會調用ClassDerivedFromMySuperClass :: preSend()和ClassDerivedFromMySuperClass :: postSend()。 – 2014-06-25 15:59:46

+0

問題與解答關於java – Tom 2014-06-25 16:10:27

1

你不能強制子類調用基類。你可以做的一件事是將你的發送方法改變成一個基本的(最終)「發送」和一個「發送核心」(虛擬),這將被子類覆蓋。基地「發送」會設置一些標誌,說明「sendcore」沒有被調用,然後調用「sendcore」。當它返回時,它可以檢查子「sendcore」是否調用了基類。

0

Java沒有內建強制調用超類方法。一種方法是在超類中使用私有標誌和委託方法。事情是這樣的:

public class Super { 
    private boolean inSend; 
    private boolean superCalled; 
    public final void send() { 
     inSend = true; 
     superCalled = false; 
     doSend(); 
     inSend = false; 
     if (!superCalled) { 
      throw new IllegalStateException("Failed to call super.doSend()"); 
     } 
    } 
    protected void doSend() { 
     if (!inSend) { 
      throw new IllegalStateException("Cannot call doSend() directly"); 
     } 
     superCalled = true; 
     // base class functionality 
    } 
} 
0

沒有關鍵字強制執行這一點。在我看來,你要麼

  1. 提供的所有信息的子類(通過受保護的方法或什麼不可以),它需要完全地覆蓋和改變send調用本身,或...
  2. 文檔的API,因此已知他們最終必須通過super自己撥打send。我想大多數重寫超類方法的人都會這樣做,如果有足夠的類被抽象出來的話。
5

您可以通過添加一個抽象方法(沒有看到另一種方式)做到這一點:

abstract class MyClass 
{ 

public final void send() // forbid changing this. 
{ 
// do something 
doSend(): 
} 

protected abstract doSend(); // no external calls 

} 
2

概念上,這就像'委託給一個孩子。爲了達到這個目的,父類應該實現調用抽象方法的最終方法,該方法應該是孩子應該實現的。

abstract class Parent { 

    public final void invoke() { 
     // pre invoke code 
     doInvoke(): 
     // post invoke code 
    } 

    protected abstract doInvoke(); // child should implement this 
} 
4

http://en.wikipedia.org/wiki/Call_super

什麼你想要做的是一個反模式;你可以做到這一點(許多Java核心類做),但你不應該 - 除非你有一個很好的理由。

除了這一點,這裏提供的所有答案都是正確的。

+2

這就是我一直在尋找的東西。我強烈要求用戶致電父母,但我不知道原因和解決方案。 – farzan 2015-01-19 10:44:51