从父类构造器调用子类覆盖方法看Java初始化过程

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
 * 
 * 
 * 
 */

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值