您的位置:首页 > 编程语言 > Java开发

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

2007-03-07 18:37 525 查看
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 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息