1. 程式人生 > >[java][30]不要在父類的構造方法中呼叫可能被子類覆寫的方法

[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);

return name.toUpperCase();
}

}

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. 總結

子類初始化會呼叫父類的構造方法,當父類構造方法呼叫被子類覆寫的方法時,往往由於子類初始化未完成導致異常。

所以,不要在父類的構造方法中呼叫可能被子類覆寫的方法!