2011-06-06 163 views
11

在爲我的決賽學習時,我在我正在學習的書中發現了以下聲明。考慮以下代碼:Java繼承 - 構造函數

class A { 
    public A(int x) { } 
} 

class B extends A { 
    public B(int x) { } 
} 

是否必須在類B(super(x))的構造函數中調用類A的構造方法。該書指出,它不是強制性的,因爲它們具有確切的參數數量和類型。但是,當我嘗試這在Java編譯器,下面的錯誤被拋出:A類

構造一個不容 應用到給定類型;要求: INT發現:沒有參數的原因: 實際的和正式的參數列表 長度

+2

這本書是錯誤的。 – Bohemian 2011-06-06 07:39:33

回答

17

編譯器會自動插入在一開始super()不同。

然而,甚至構造函數參數super()(不帶參數)被添加,它調用超類的構造函數的默認。你沒有一個,所以錯誤。

你必須指定super(x)(調用A(x)),或者定義一個無參數的構造函數。

順便說一句,Eclipse的編譯器提供了一種方式更好的錯誤消息:

隱超構造函數A()是不確定的。必須明確調用另一個構造函數

+0

錯誤引發在這一行:「public B(int x){}」。我在問題中發佈的代碼是我想要編譯的所有代碼(只是類定義,根本沒有實例化)。 – 2011-06-06 07:17:35

+0

它只會插入'super()'。它不會插入'super(int)'。因此,這裏的錯誤。在這種情況下,他確實需要調用'super(x)'。請參閱http://download.oracle.com/javase/tutorial/java/IandI/super.html。 – MGwynne 2011-06-06 07:19:03

+0

@MGwynne是的,只是更新 – Bozho 2011-06-06 07:19:06

1

這種情況發生在沒有默認構造函數的情況下並且您正在使用默認構造函數創建實例時。因爲如果你有任何參數化的構造函數,那麼編譯器不會爲你插入默認的構造函數,而是你必須定義。

4

它看起來像編譯器試圖創建的超默認構造函數的調用與super(),這不是可供選擇:

required: int 
found: no arguments 

但是,回到你的書:我從來沒有聽說過的規則的那如果實際構造函數與直接超類中的構造函數具有完全相同的參數列表,則可以跳過構造函數中的super語句。只隱式地添加對超類的默認構造函數的調用(super()),但要求超類具有默認構造函數

相較於什麼是寫在你的書(或相反的書面文本的理解),這裏是從語言規範的句子:

如果構造體不具有顯式的構造函數開始調用 並且聲明的構造函數不是原始類Object的一部分,則 構造函數體由編譯器隱式承擔,以超級 類構造函數調用「super();」,調用構造函數它的 直接超類,沒有任何argume NTS。

4

如果你有一個默認的構造函數(無參數的構造函數),當您擴展B一個基類,你並不需要顯式調用super()因爲它叫什麼辦法。

但是,當你有一個參數的構造函數,在B使帶參數的構造器時,你需要在super()一個參數來傳遞對A

例如:

class A { 
    public A(int x) { } 
    } 

    class B extends A { 
    public B(int x) 
    { 
     super(x); // need to specify the parameter for class A 
     //... 
    } 
    } 
0

這裏有必要在Java的情況下調用超級類的構造函數。因此,無論何時生成子類的構造函數,超類的構造函數都是由IDE自行創建的。

這是因爲每當基類構造函數需要參數時,編譯器認爲它們將被基類構造函數填充。在默認的構造函數的情況下,它是可以的。無需在子類中調用super()。