我觉得应该是new B()的时候同时调用父类A的构造方法了,但因为show()方法被覆写,所以在A的构造方法中实际调用的是B的show()方法,但此时B尚未实例化(在A的构造方法之后),所以num为0(你可以把B的num设为static再观察),输出
B0,接下来是B的构造方法,这时B已经实例化,num也被分配,所以输出B10。个人见解
B0,接下来是B的构造方法,这时B已经实例化,num也被分配,所以输出B10。个人见解
{
public static void main(String[] args)
{
B b = new B();
}
}class A
{
int num = 5;
A()
{
show();
}
public void show()
{
System.out.println("A"+num);
}
}class B extends A
{
int num = 10;
B()
{
super();
show();
return;
}
public void show()
{
System.out.println("B"+num);
}
}
有点捉急的改下代码排版,,
有看到我改的B的构造函数么,首先,你要明确 在子类中构造函数肯定会访问 父类的空参的构造函数(指定的父类的构造函数另当别论了),也就是 super()这一步,当A B 加载进内存时 在代码区域,你new了一个B 时会访问到A的空参的构造函数,这个时候堆内存中 B的情况 是 num并没有显示初始化,而是默认初始化,也就是说这个时候 B的 num 的值默认是 0,此时访问到的A的构造函数中调用了 show()方法,而在B中已经重写了A的此方法,也就是说其实调用的是B的show()方法,这个时候输出自然是 B0 了,只有当 super() 即父类初始化完毕了,才进行子类的成员变量的显示初始化, super() 就是一个分水岭,这一步结束了,num的值立刻就被显示初始化变成 10 (这一步的显示初始化紧紧跟着super()),之后再调用 show(),这就不用多说了吧, 输出 B10,是一定的啦。。呼呼,,
真心欢迎大神指出理解中的错处,谢谢了
B(){
int num=0; //num初始化为0
A(); //默认调用父类无参构造方法,num还没有被赋值10
num=10; //执行完A()之后,再进行num的赋值
show();
}A(){
num=0;
??(); //A可能还有父类,但A的父类的构造方法不影响本程序的结果。
num=5; //属性被赋值。
show(); //方法被覆写
}由于两次show()都是B中的被覆写的show(),子类中调用属性时先从子类中查找,子类中没有时再从父类中找。父类中的方法调用父类中的属性(把B中show()改为super.show()查看结果比较),如果找不到属性会报错。
{
public static void main(String[] args)
{
B b = new B();
}
}class A
{
int num = 5;
A()
{
show();
}
public void show()
{
System.out.println("A"+num);
}
}class B extends A
{
int num = 10;
B()
{
super();
show();
return;
}
public void show()
{
System.out.println("B"+num);
}
}
1、用 Eclipse 调试,单步走,我们可以看到它先走 A 的初始化,调用的 show 时访问 B 的 num。
2、把 B 的 num 类型改成 Integer 就一目然了。