子類別建構子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");
}
}
當繼承自一個類的時候,構造方法就會首先調用super()方法。如果沒有顯式的寫這個語句,那麼編譯器就會自動插入這個語句。這就是為什麼我們上面的那個例子程序會先調用super的構造方法。
但要切記, 雖然調用了父類的構造方法,但只建立了一個對象也就是子對象。
之所以要調用父類的構造方法,是因為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。
Implicit super constructor Super() is undefined. Must explicitly invoke another constructor。
編譯器錯誤是因為預設的super()無參的建構子是沒有定義的。在Java中,如果一個類沒有定義建構子,編譯器會自動插入一個預設的無參的建構子。
但是,如果類中定義了一個建構子,編譯器就不會自動插入無參的建構子了,所以如果我們不顯示定義一個無參的建構子,那麼這個建構子就不存在。
但是,如果類中定義了一個建構子,編譯器就不會自動插入無參的建構子了,所以如果我們不顯示定義一個無參的建構子,那麼這個建構子就不存在。
上一小節,我們知道,如果子類的建構子中,沒有顯示的調用父類的建構子,那麼,編譯器就會插入super(),也就是自動調用無參的建構子。但是此時,父類沒有無參的建構子,所以就會報錯了。
解決這個問題很簡單,我們可以給父類插入一個無參的建構子,或者在子類建構子中顯示的調用的父類有參建構子。
在子類的建構子中顯示的調用父類的建構子
下面的代碼是正確的。
簡單的說,在使用的時候,子類的建構子必須調用父類的建構子,不管有沒有顯示的聲明。所以,被調用的父類建構子,一定在定義好!
為什麼JAVA在一個類已經實現了一個帶參的建構子的時候,不實現預設的無參建構子?
這是個很有趣的問題。我們知道如果在一個類中沒有聲明一個建構子,那麼編譯器會隱式的幫我們實現一個無參的建構子,但如果我們一旦一個建構子,不管帶不帶參數,那麼編譯器都不會提供預設的建構子,所以這麼做的原因是為什麼呢?
有一個原因就是,如果我們給所有的類都自動實現一個無參的建構子,就可能出現問題,會打破類的設計原則。
比如說,考慮這個Scanner類,他有幾個建構子,你可以通過這幾個建構子,聲明你想要讀取數據的來源,如果編譯器增加了無參的建構子,那麼你不給定讀取的數據源,就會報錯,程序無法執行,因為我們不能不指定一個數據源就讓他去讀取數據。
比如說,考慮這個Scanner類,他有幾個建構子,你可以通過這幾個建構子,聲明你想要讀取數據的來源,如果編譯器增加了無參的建構子,那麼你不給定讀取的數據源,就會報錯,程序無法執行,因為我們不能不指定一個數據源就讓他去讀取數據。
留言
張貼留言