Base.java
public class Base {
private String baseName="base";
private static String testname="父类静态字段";
public Base(){
this.callName();
}
public void callName(){
System.out.println("父类构造器"+baseName);
}
}
Sub.java
public class Sub extends Base{
private String baseName="Sub";
@Override
public void callName() {
System.out.println(baseName);
}
public static void main(String[] args) {
Base player=new Sub();
}
}
上面这个是构建个子类对象,用无参方法构建子类对象,会先构建父类的无参构造器,这里父类的无参构造器里面调用了一个callName方法,但因为子类重写了这个方法,导致转入子类的callName方法中 最后输出Null,
看下调试过程
new 一个子类
会先找继承的父类
调用父类的构造器
看一下他的实例字段
进入到父类构造器,找到方法,可以看到,我们是新建子类对象,他直接先去找你父类的构造器,没有访问子类的实例字段,所以baseName其实是null
因为你是重写了这个方法,而且new 的是子类对象 会优先调用子类重写的方法,那这里通过这个callName直接就进入了子类的callName里面,baseName就是Null
会发现此时baseName是null,然后输出了一个Null
父类的构造方法结束 然后才访问子类的实例字段,那这时候已经晚了,输出已经是null了
over
那如果不重写这个callName方法,那就会直接访问父类的callName()这个方法,输出
如果加入顺序,有初始化构造块的话,按如下排列