2011-07-22 117 views
6

爲什麼System.out.println(super)不允許?爲什麼System.out.println(super)不允許?

System.out.println(this); 

這是OK並且this.toString()被自動調用和打印。 當然,實例變量是OK,而不是this

但是,thissuper可以以我所知的相同方式使用。

System.out.println(super); 

那麼爲什麼這會失敗呢?我認爲它應該隱含地稱爲super.toString()。 我已閱讀Java規範文檔,但我沒有找到原因。

+2

它是如何失敗?這是一個編譯錯誤?運行時異常?或意外的行爲? (例如'System.out.println(super)'輸出與'this.toString()'相同的東西) –

+0

問題是編譯錯誤發生在使用'super'的第二種情況。錯誤訊息是「'。'預期「,它看起來像一個語法錯誤。 – JaycePark

+0

*「這是一個簡單的問題。」*請注意「生命的意義是什麼?」是一個簡單的問題。這是更難的答案。 ;) –

回答

4

貫徹super一個獨立的變體,打破虛擬方法分派將是一個非常糟糕的想法。

讓我們想想了一會兒。

abstract class Base { 
    abstract String Description(); 
    String toString() { return "Base"; } 
} 
class Derived extends Base { 
    String Description() { return "Derived description"; } 
    String toString() { return "Derived"; } 

    static void use(Base instance) { 
     System.out.println(instance.toString()); 
     System.out.println(instance.Description()); 
    } 
} 

現在,讓我們把你的建議,並假設super是有效的,不會有什麼建議;那麼我們可以在Derived寫:

class Derived extends Base { 
    // Previous declarations omitted. 
    void useSuper() { Derived.use(super); } 
    void useThis() { Derived.use(this); } 

    static void main() { 
     Derived instance = new Derived(); 
     instance.useThis(); 
     instance.useSuper(); 
    } 
} 

現在,如果我理解你,你建議的主要功能應該按順序打印:

  • toString()Derived實現:「派生」。
  • Description()Derived實現: 「基地」: 「派生的描述」
  • toString()Base實施。
  • 執行Description()Base它不存在。而我能想到的兩種解決方案會導致更大的問題:
    • 引發異常:恭喜,您現在可以打破任何依賴抽象方法實際實施而不考慮它的程序。 (你怎麼知道函數會調用抽象方法?)
    • Derived返回實現:中斷一致性。

總之,這樣的使用詞語super的概念性分解面向對象的編程。

+0

謝謝,我認爲你的回答非常清楚基於OOP。 – JaycePark

0

this指您當前的對象super指的是超類,您當前對象直接從類繼承的類(或者它可以是超類的構造函數)。所以

System.out.println(this) 

打印您的對象的toString()方法,但

System.out.println(super) 

失敗,因爲超是不是一個對象(,因此沒有toString()方法)。

+2

爲了進一步闡明,'super'指的是一個類,它有一個toString()方法,但該方法不是靜態的;它不能在課堂上被調用。它需要在一個對象上調用,比如'this'。 – Steven

+0

如果你仔細想想,即使超級是一個對象,它也會是這個對象。 –

+0

@StevenNoto,如果super指的是一個類,並且沒有靜態的toString()方法,那麼這個代碼是如何工作的呢?System.out.println(super.toString());' –

-5

超級與僅調用靜態方法有關。如果您使用super實際調用您的對象本身的非靜態方法,即調用this。例如,您可以說System.out.println(super.toString())。這將工作,並將運行實際班的toString()

我認爲這是通過super作爲其他方法的參數被禁止的原因。

+0

不,使用super調用非靜態方法也可以。 toString不是一個靜態方法,調用super.toString()將正確地調用祖先類的toString()。 – Raze

+0

我說過它的工作原理。但它調用實際類的toString(),而不是它的超類! – AlexR

+3

很確定這是錯誤的。你可能想要在簡單的類上實際測試這個,我做了,並得到它稱爲超類的方法。 – Jodaka