初始化顺序(Thinking in Java中的一段有意思的例子)

abstract class Glyph {
  abstract void draw();
  Glyph() {
    System.out.println("Glyph() before draw()");
    draw();
    System.out.println("Glyph() after draw()");
  }
}

class RoundGlyph extends Glyph {
  int radius = 1;
  RoundGlyph(int r) {
    radius = r;
    System.out.println(
      "RoundGlyph.RoundGlyph(), radius = "
      + radius);
  }
  void draw() {
    System.out.println(
      "Draw():RoundGlyph.draw(), radius = " + radius);
  }
}

public class PolyConstructors {
  public static void main(String[] args) {
    new RoundGlyph(5);
  }
}
这是Thinking in Java中多态一章中的一个例子,程序运行的结果是什么呢,首先应该分析一下代码。
在分析这段代码之前,需要知道的是:
(1) 在采取其他任何操作之前,为对象分配的存储空间初始化成二进制零。
(2) 子类首先调用基础类构建器。
(3) 按照原先声明的顺序调用成员初始化代码。
(4) 调用衍生类构建器的主体。
由这四点可以知道,在主函数实例化一个RoundGlyph,调用它的构造函数,发现它是一个继承了Ploy的类,那么首先在构造器内隐式调用父类构造器,在这时,由第一条我们知道,这时候radius的值被初始化为0了,然后执行父类构造器,得到了第一个输出"Glyph() before draw()",执行下一行,要调用虚函数draw(),自动找到了子类的覆盖的函数draw(),执行得到了第二行输出"Draw():RoundGlyph.draw(), radius = 0",注意,这里是0而不是子类的赋值1,因为这里还没有执行到子类的赋值,所以只得到虚拟机为该变量的初始化0,然后执行下一行得到了"Glyph() after draw()",然后为子类初始化成员变量得到radius的值为1,然后执行构造器得到了radius的值为5,然后输出"RoundGlyph.RoundGlyph(), radius = 5",所以最后得到的输出结果应该是:
Glyph() before draw()
Draw():RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值