我有个密码:
class Egg2 {
protected class Yolk {
public Yolk() { System.out.println("Egg2.Yolk()");}
public void f() { System.out.println("Egg2.Yolk.f()"); }
}
private Yolk y = new Yolk();
public Egg2() { System.out.println("New Egg2()");}
public void insertYolk(Yolk yy) { y = yy; }
public void g() { y.f(); }
}
public class BigEgg2 extends Egg2 {
public class Yolk extends Egg2.Yolk {
public Yolk() { System.out.println("BigEgg2.Yolk"); }
public void f() { System.out.println("BigEgg2.Yolk.f()"); }
}
public BigEgg2() { insertYolk(new Yolk()); }
public static void main(String[] args) {
Egg2 e2 = new BigEgg2();
e2.g();
}
}产出如下:
Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk
BigEgg2.Yolk.f()问题:现在我无法理解这些对象和类是如何初始化的。我觉得命令应该是这样的:
这个阶段的外表是什么?
为什么会这样?
发布于 2019-04-10 23:06:17
当您使用超类构造函数调用类的构造函数时,会发生很多事情,而且它们都有实例变量初始化器。
BigEgg2的构造函数没有显式调用任何超类构造函数,因此编译器插入了对Egg2默认构造函数的调用。(同样的情况也适用于调用Egg2构造函数的Object构造函数,但该构造函数没有打印任何内容。)
在超类构造函数调用完成后,将运行超类的实例初始化器(如果有的话)。这意味着在声明它们的地方初始化了任何实例变量。在这里,为实例变量Egg2.Yolk创建一个y实例。这是输出Egg2.Yolk()的第一行。
然后,超类构造函数的主体最终被执行。这是输出New Egg2()的第二行。
BigEgg2类有自己的Yolk类来实例化,以便在自己的构造函数中传递给insertYolk。它创建一个Yolk,它在Egg2中对嵌套类Yolk进行子类分类。首先调用超类构造函数,它引用Egg2.Yolk类。这是输出Egg2.Yolk()的第三行。注意,这是与输出的第一行相同的print语句。
类BigEgg2.Yolk的这个对象被分配给超类方法Egg2.insertYolk中的实例变量y。这发生在BigEgg2.Yolk构造函数的主体中。BigEgg2.Yolk构造函数负责输出BigEgg2.Yolk的第四行。注意,y变量现在引用的是BigEgg2.Yolk的一个实例。此时,main第一行的执行已经完成:Egg2 e2 = new BigEgg2();。
当您调用e2.g()时,您正在调用BigEgg2从Egg2继承的g()方法,该方法调用y.f(),其中y是一个Egg2.Yolk。由于多态性的原因,f()方法在BigEgg2.Yolk中被调用。这是输出BigEgg2.Yolk.f()的第五行。
https://stackoverflow.com/questions/55622308
复制相似问题