這篇文章總結(jié)了一個關(guān)于Java構(gòu)造函數(shù)的常見問題硫兰。
1.為什么創(chuàng)建子類的對象也調(diào)用父類的構(gòu)造函數(shù)隆檀?
class Super {
String s;
public Super(){
System.out.println("Super");
}
}
public class Sub extends Super {
public Sub(){
System.out.println("Sub");
}
public static void main(String[] args){
Sub s = new Sub();
}
}
輸出:
Super
Sub
當(dāng)從另一個類繼承時龄广,必須在構(gòu)造函數(shù)中首先調(diào)用super() 惰赋。 如果沒有宰掉,則編譯器將插入該調(diào)用。 這就是為什么在創(chuàng)建Sub對象時也調(diào)用super構(gòu)造函數(shù)的原因赁濒。
這不會創(chuàng)建兩個對象贵扰,只創(chuàng)建一個子類對象。 有父類構(gòu)造函數(shù)調(diào)用的原因是流部,父類可能有私有字段需要由其構(gòu)造函數(shù)初始化。
編譯器插入父類構(gòu)造函數(shù)后纹坐,子類構(gòu)造函數(shù)如下所示:
public Sub(){
super();
System.out.println("Sub");
}
2.常見錯誤消息:隱式父類構(gòu)造函數(shù)對于默認(rèn)構(gòu)造函數(shù)是未定義的
這是很多Java開發(fā)人員看到的編譯錯誤消息:
“隱式父類構(gòu)造函數(shù)對于默認(rèn)構(gòu)造函數(shù)是未定義的枝冀,必須定義一個顯式構(gòu)造函數(shù)”
出現(xiàn)此編譯錯誤是因?yàn)槟J(rèn)的父類構(gòu)造函數(shù)未定義舞丛。 在Java中,如果一個類沒有定義構(gòu)造函數(shù)果漾,編譯器默認(rèn)會為該類插入一個默認(rèn)的無參構(gòu)造函數(shù)球切。 如果構(gòu)造函數(shù)是在父類中定義的,在這種情況下绒障,Super(String s)吨凑,編譯器不會插入默認(rèn)的無參數(shù)構(gòu)造函數(shù)。
子類的構(gòu)造函數(shù)(帶參或無參)將調(diào)用無父類的無參構(gòu)造函數(shù)户辱。 由于編譯器試圖向子類中的2個構(gòu)造函數(shù)中插入super() 鸵钝,但父類的默認(rèn)構(gòu)造函數(shù)未定義,因此編譯器會報告錯誤消息庐镐。
要解決這個問題恩商,只需要
- 添加一個Super() 構(gòu)造函數(shù)給Super類
public Super(){
System.out.println("Super");
}
或者2)刪除自定義的父類構(gòu)造函數(shù),
或者3)將 Super(value) 添加到子構(gòu)造函數(shù)必逆。
3. 在子類構(gòu)造函數(shù)中顯式調(diào)用父類構(gòu)造函數(shù)
子類構(gòu)造函數(shù)使用參數(shù)顯式調(diào)用父類構(gòu)造函數(shù)怠堪。 父類構(gòu)造函數(shù)被定義,并且被調(diào)用名眉。
4. 規(guī)則
簡而言之粟矿,規(guī)則是:子類構(gòu)造函數(shù)必須由程序員顯式調(diào)用或由編譯器隱式地調(diào)用。 無論哪種方式损拢,被調(diào)用的超級構(gòu)造函數(shù)都必須被定義陌粹。