代碼示例如下:
class Animal { private String name; public Animal(String name) {} }
class Penguin extends Animal{}
編輯器會提示 Implicit super constructor is undefined for default constructor. Must define an explicit constructor ( 隱含的父類構造方法沒有為默認的構造方法定義,必須定義一個明確的構造方法) , 使用編輯器提示會自動生成如下代碼:
class Penguin extends Animal{ public Penguin(String name) { super(name); } }
分析錯誤原因,主要從兩個方面:默認構造方法生成、子類構造方法默認調用父類無參的構造方法
默認的構造方法:在Java中如果一個類沒有定義構造方法,編譯器會默認幫忙生成一個無參的構造方法,如果已經定義了構造方法那么就不會再生成無參的構造方法,生成的無參構造方法貌似下面:
1 public Penguin(){}
但是真實的情況並不是現在看到的這樣。為什么不是這樣,是因為在Java的繼承中,要求子類的構造方法必須調用父類的構造方法,如果子類沒有顯示的調用父類的構造方法
那么編譯器就會隱含調用父類的無參構造方法,這樣就可以解釋為什么報錯及修復的方法。在之前的例子中編譯器默認生成的構造方法如下:
public Penguin(){ super(); }
這樣就清楚了,編譯器生成了一個無參的構造方法,同時調用了父類的無參構造方法調用方式:super() ,又因為父類定義了有參的構造方法所以就不會有無參的構造方法,導致報錯。
修改方案:
父類加入無參的構造方法
public Animal(){}
子類定義自己的無參或有參的構造方法,同時用super關鍵字顯示調用父類的有參構造方法,因為父類沒有無參的構造方法(Java默認調用父類無參的構造方法)
public Penguin(){ super("defaultName"); } 或 public Penguin(String myName) { super(myName); }
去掉父類的自定義構造方法使用默認的構造方法
默認構造方法
在java語言中,每個類至少有一個構造方法。如果程序中沒有顯式定義任何構造方法,
那么java語言將自動提供一個隱含的默認構造方法。只要程序中已經顯式定義了構造方法。
那么java語言將不再提供隱含的默認構造方法。
子類為什么必須調用父類的構造方法
因為子類繼承父類,會繼承到父類的特性和行為,所以子類在初始化時必須要看父類是如何對自己的數據進行初始化的。子類調用父類的構造方法有來初始化父類私有的變量及做其它額外的工作。所以子類在進行對象初始化時,先調用父類的構造函數
