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

结果:

[java][30]不要在父类的构造方法中调用可能被子类覆写的方法_第1张图片

SeniorClass ju2=new JuniorClass(); 

结果:

[java][30]不要在父类的构造方法中调用可能被子类覆写的方法_第2张图片

}

}

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. 总结

子类初始化会调用父类的构造方法,当父类构造方法调用被子类覆写的方法时,往往由于子类初始化未完成导致异常。

所以,不要在父类的构造方法中调用可能被子类覆写的方法!

你可能感兴趣的:(java)