class Glyph {
void draw() { System.out.println("Glyph.draw()"); }
Glyph() {
System.out.println("Glyph() before draw()");
draw();//
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private int radius = 1;
RoundGlyph(int r) {
radius = r;
System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius);
}
void draw() {
System.out.println("RoundGlyph.draw(), radius = " + radius);
}
}
public class PolyConstructors {
public static void main(String[] args) {
new RoundGlyph(5);
}
}
//你的答案是什么?
/*以上代码以及初始化实质来自 Java编程思想
Output:
Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5
编写构造器时有一条有效的准则:“用尽可能简单的方法使对象进入正常状态;如果可以的话
避免调用其他方法”在构造器内为一能够安全调用的那些方法是基类中的final方法
*///:~
/* 初始化实质:
1)在其他任何事物发生之前,将分配给对象的存储空间初始化为二进制的零
2)调用基类(父类)构造器。此时调用被覆盖的draw()方法(要在调用RounGlyph构造器之前调用)
,由于步骤一的关系,我们发现Radius的值为0
3)按照声明的调用顺序调用成员的初始化方法
4)调用导出类的构造主体
*/
/*个人总结:初始化执行顺序
* 1)从基类到导出类顺序实现静态初始化块
* 2)导出类new一个对象的时候从导出类的构造方法开始
* 1.系统为实例成员默认初始化,基本数据类型为0,引用类型为null 上面的例子即为radius = 0
* 2.调用super() 即构造方法的第二步为调用为调用父类的构造器,所以上面例子 的第一个输出是0而不是1
* 3.实现实例成员的初始化 上面的例子即为radius = 1
* 4.实现构造方法里的代码 上面的例子即为radius = 5 所以最后输出是5
*
*
*
*/
从父类构造器调用子类覆盖方法看Java初始化过程
最新推荐文章于 2021-09-26 10:26:38 发布