请看下面这道选择题:
下面代码的输出是什么?
public class Base
{
private String baseName = "base";
public Base()
{
callName();
}
public void callName()
{
System. out. println(baseName);
}
static class Sub extends Base
{
private String baseName = "sub";
public void callName()
{
System. out. println (baseName) ;
}
}
public static void main(String[] args)
{
Base b = new Sub();
}
}
编译看左,运行看右
意思是使用多态创建对象,先去父类查看方法是否存在,如果存在,再去子类查看方法,
如果子类存在,直接调用子类的方法,
如果子类不存在,调用父类的方法
如果父类不存在,会直接报错
分析:
从 Main 还是开始看,使用多态创建对象,Base b = new Sub() ,根据编译看左,运行看右的原理:先构造父类对象
调用 callName 方法,先去子类查找,有无该方法
子类有方法,此时直接输出,但是由于子类还未初始化,所以输出的是 null
debug 查看步骤:
结果与我们分析的一致
下面是拓展分析:
如果此时我们把子类的方法修改一下名字,那么父类会查不到子类的方法,此时直接调用 父类的方法,输出的就是 base 了
再次拓展,如何才能输出子类的 sub 呢?
再次分析过程:
调用 Base b = new Sub() 方法的过程,输出 null 以后,父类加载结束,此时开始加载子类,通过 debug 可以验证
所以要想输出 sub,只需要再次调用 callName 方法,因为 Sub 已经经历了初始化