[java][30]不要在父類的構造方法中呼叫可能被子類覆寫的方法
java小白的學習記錄......
1. 首先看例項
1)父類
public class SeniorClass
{
public SeniorClass()
{
System.out.println("父類構造方法");
toString(); //父類的構造方法呼叫toString()
}
public String toString()
{
System.out.println("Senior");
return "Senior";
}
}
2)子類
public class JuniorClass extends SeniorClass
{
private String name;
public JuniorClass()
{
super(); //呼叫父類的構造方法
System.out.println("子類構造方法");
name="Junoir";
}
public String toString() //覆寫父類的toString()
{
System.out.println(name);
}
}
3)測試
public class Test
{
public static void main(String[] args)
{
SeniorClass se=new SeniorClass();
結果:
JuniorClass ju=new JuniorClass();
SeniorClass ju2=new JuniorClass();
結果:
}
}
2. 分析
初始化父類沒問題,初始化子類卻出錯。
點選上圖出錯原因的藍色連結,可以定位到程式對應位置。
進行Debug,除錯 JuniorClass ju=new JuniorClass() 這一行,發現執行順序與 上圖出錯原因的倒序 一致。
1)進入Test.main()的 JuniorClass ju=new JuniorClass();
2)初始化子類,進入子類建構函式,JuniorClass.JuniorClass();
3)子類繼承父類,進入父類建構函式,由JuniorClass.JuniorClass()的super() 進入 SeniorClass.SeniorClass()
4)SeniorClass.SeniorClass()首先列印“父類構造方法”,然後呼叫toString()方法,
關鍵問題:toString()被子類覆寫,此時進入子類的toString();
子類的name屬性還沒有被初始化!故子類toString()的System.out.println(name)打印出null;
子類toString()的return name.toUpperCase()返回1個空指標。
5)main()接收到空指標,報錯!
3. 總結
子類初始化會呼叫父類的構造方法,當父類構造方法呼叫被子類覆寫的方法時,往往由於子類初始化未完成導致異常。
所以,不要在父類的構造方法中呼叫可能被子類覆寫的方法!