2016-02-23 143 views
-1

所有類都至少有一個構造函數。如果一個類不顯式聲明任何類,則Java編譯器會自動提供一個名爲默認構造函數的無參構造函數 。如果該類沒有其他父類,則此構造函數的默認構造函數將調用父類的無參數構造函數,或者 對象構造函數。 如果父代有 沒有構造函數(Object有一個),編譯器會拒絕 程序。爲什麼編譯器會抱怨超類沒有構造函數,當默認的構造函數被自動賦予一個沒有構造函數的類?

source

不過呢,Object是Java中的每個類的(直接或間接)父。

假設我們有一個類A,它沒有明確擴展任何類,所以它隱式擴展了Object。另外假設,A沒有明確提供構造函數,因此編譯器會自動添加一個默認的構造函數,它將調用其超類(並且Object確實具有構造函數)的構造函數。

現在假設我們有一個擴展類A的類B,它沒有提供顯式構造函數,所以編譯器自動爲它提供一個默認的構造函數;這個默認構造函數試圖從A調用構造函數。

現在爲什麼編譯器錯誤在B,當編譯器已經提供了一個(默認)構造函數A(被調用Object的構造,以及Object有一個)?


編輯:

測試:編譯成功! 這是否意味着本教程中的最後一句不正確?

class A extends B { 
    public static void main(String [] args) { 
     //A a = new A(); 
     System.out.println("Yayyy"); 
    } 
} 

class B { 
} 
+6

你測試過了嗎?我絕對期待這一點。 –

+0

@LouisWasserman不,信任它,因爲它在*官方* Java教程。 – Solace

+2

僅僅因爲它的官方並不意味着它是有道理的。它只是說所有類在段落的開頭至少有一個構造函數!所以沒有沒有構造函數的東西。 –

回答

4

首先一些術語:

  • 無參數構造:無參數的構造;
  • 可訪問的無參數構造函數:超類中的無參數構造函數對子類可見。這意味着它是公開的或受保護的,或者如果兩個類都在同一個包中,則包訪問;和
  • 默認構造函數:編譯器在類中沒有顯式構造函數時添加的公共無參數構造函數。

所以所有的類都至少有一個構造函數。

子類構造函數可能指定在執行子類的構造函數中的代碼之前調用超類中的哪個構造函數。

如果子類構造函數未指定要調用哪個超類構造函數,則編譯器將自動調用超類中的可訪問無參數構造函數。

如果超類沒有無參數構造函數或者它不可訪問,那麼未指定要調用的超類構造函數(在子類構造函數中)是編譯器錯誤,因此它必須指定必須

例如:

public class Base { } 
public class Derived extends Base { } 

這是好的,因爲如果你明確地添加沒有構造函數的Java放在一個公共的默認構造函數爲您服務。

public class Base { } 
public class Derived extends Base { public Derived(int i) { } } 

還行。

public class Base { public Base(String s) { } } 
public class Derived extends Base { } 

以上是編譯錯誤,因爲Base沒有默認構造函數。

public class Base { private Base() { } } 
public class Derived extends Base { } 

這也是一個錯誤,因爲Base的無參數構造函數是私有的。

相關問題