在core java 2书中有下面一段话:
调用构造器的具体处理步骤:
1、所有数据域被初始化为默认值。
2、按照在类声明中出现的次序依次执行所有域初始化语句和初始化块。
3、如果构造器第一行调用了第二个构造器,则执行第二个构造器主体。
4、执行这个构造器主体。
可是从下面的代码输出结果看却与上面的有些矛盾
class A {
private int radius = 10;
public A()
{
draw();
}
public void draw()
{
}
}
class B extends A
{
private int radius = 1;
public B()
{
}
public void draw()
{
System.out.println(radius);
}
public static void main(String[] args)
{
B a = new B();
}
}
输出的结果为:
0
如果按上面的第二条和条三条的顺序来执行的话应该输出1才是啊, 因为在调用第二个构造器之前完成了 “按照在类声明中出现的次序依次执行所有域初始化语句和初始化块。”,那么这时的radius就是1了啊?
大家怎么看呢?
------解决方案--------------------
输出结果是0没错!
基类的构造器先于子类的构造器被调用。
而在基类的构造器内部调用draw(); 根据多态行为,应该调用子类的draw()方法,就是System.out.println(radius);
但此时,由于子类的初始化工作还没进行。radius 也就没有被初始化成1。所以此时输出的是0
------解决方案--------------------
1楼是正解,如果该成下面这样,就有1输出了。
class A {
private int radius = 10;
public A() //构造方法
{
draw();
}
public void draw()
{
}
}
class B extends A
{
private int radius = 1;
public B()
{
}
public void draw()
{
System.out.println(radius);
}
public static void main(String[] args)
{
B a = new B();
System.out.println(a.radius);
}
}
------解决方案--------------------
程序的入口是main方法,并且main方法是静态的,而private int radius = 10;不是静态的,他必须要在实例化对象以后才被执行。所以我在你那个程序最后加上了System.out.println(a.radius); 意思就是,在前面实例化对象a以后再输出。也可以这样改。在后面加上a.draw();自己去揣摩一下,应该可以理解的。1楼说的很正确:由于子类对象的初始化工作还没进行。radius 也就没有被初始化成1。所以此时输出的是0 。
------解决方案--------------------
2、按照在类声明中出现的次序依次执行所有域初始化语句和初始化块。这个规则是在实例对象的时候遵守的。。。