跳到主要內容

子類別建構子super觀念

父類別子類別建構子觀念

寫程式編譯的時候出現一個 錯誤

IMPLICIT SUPER CONSTRUCTOR IS UNDEFINED FOR DEFAULT CONSTRUCTOR. MUST DEFINE AN EXPLICIT CONSTRUCTOR

Implicit super constructor ZHero() is undefined. Must explicitly invoke another constructor

Google找到這篇文章寫得很棒
https://ddnews.me/tech/qka5h3zp.html




關於JAVA建構子(CONSTRUCTOR)的常見問題總結

這篇文章總結了Java使用建構子中最常遇到的五個問題!

1 為什麼調用子類的構造方法的時候,預設會調用父類的構造方法

看下面這個簡單的例子:
package cc;

public class Sub extends Super {
    public Sub() {
        System.out.println("Sub");
    }

    public static void main(String[] args) {
        Sub sub = new Sub();
    }
}

class Super {
    public Super() {
        System.out.println("Super");
    }
}

Paste_Image.png
當繼承自一個類的時候,構造方法就會首先調用super()方法。如果沒有顯式的寫這個語句,那麼編譯器就會自動插入這個語句。這就是為什麼我們上面的那個例子程序會先調用super的構造方法。
但要切記, 雖然調用了父類的構造方法,但只建立了一個對象也就是子對象。
之所以要調用父類的構造方法,是因為super類可能需要建構子來初始化一些私有的成員變數。
編譯器自動插入super構造方法後,子類的建構子就會像下面這樣:
public Sub(){
    super();
    System.out.println("Sub");
}

2 常見錯誤:IMPLICIT SUPER CONSTRUCTOR IS UNDEFINED FOR DEFAULT CONSTRUCTOR. MUST DEFINE AN EXPLICIT CONSTRUCTOR

Implicit super constructor is undefined for default constructor. Must define an explicit constructor
這個錯誤是很多開發者經常遇到的錯誤,錯誤原因就是找不到超類中的預設建構子。
看下面的代碼:
package cc;

public class Sub extends Super {

    public Sub(String s) {

    }

    public static void main(String[] args) {
        Sub sub = new Sub();
    }
}

class Super {
    String s;
    public Super(String s) {
        this.s = s;
    }
}
上面這段代碼會報錯:
Implicit super constructor Super() is undefined. Must explicitly invoke another constructor。
編譯器錯誤是因為預設的super()無參的建構子是沒有定義的。在Java中,如果一個類沒有定義建構子,編譯器會自動插入一個預設的無參的建構子。
但是,如果類中定義了一個建構子,編譯器就不會自動插入無參的建構子了,所以如果我們不顯示定義一個無參的建構子,那麼這個建構子就不存在。
上一小節,我們知道,如果子類的建構子中,沒有顯示的調用父類的建構子,那麼,編譯器就會插入super(),也就是自動調用無參的建構子。但是此時,父類沒有無參的建構子,所以就會報錯了。
解決這個問題很簡單,我們可以給父類插入一個無參的建構子,或者在子類建構子中顯示的調用的父類有參建構子。

在子類的建構子中顯示的調用父類的建構子

下面的代碼是正確的。

建構子的使用規則
簡單的說,在使用的時候,子類的建構子必須調用父類的建構子,不管有沒有顯示的聲明。所以,被調用的父類建構子,一定在定義好!

為什麼JAVA在一個類已經實現了一個帶參的建構子的時候,不實現預設的無參建構子?

這是個很有趣的問題。我們知道如果在一個類中沒有聲明一個建構子,那麼編譯器會隱式的幫我們實現一個無參的建構子,但如果我們一旦一個建構子,不管帶不帶參數,那麼編譯器都不會提供預設的建構子,所以這麼做的原因是為什麼呢?
有一個原因就是,如果我們給所有的類都自動實現一個無參的建構子,就可能出現問題,會打破類的設計原則。
比如說,考慮這個Scanner類,他有幾個建構子,你可以通過這幾個建構子,聲明你想要讀取數據的來源,如果編譯器增加了無參的建構子,那麼你不給定讀取的數據源,就會報錯,程序無法執行,因為我們不能不指定一個數據源就讓他去讀取數據。




留言

這個網誌中的熱門文章

Use Case Description(描述使用案例)

列出不重複的隨機亂數

Tomcat 讀取中文檔案的方法