首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >输出"println“顺序的原因是什么?如何在此代码中初始化对象?

输出"println“顺序的原因是什么?如何在此代码中初始化对象?
EN

Stack Overflow用户
提问于 2019-04-10 22:46:45
回答 1查看 44关注 0票数 0

我有个密码:

代码语言:javascript
复制
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();
    }

}

产出如下:

代码语言:javascript
复制
Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk
BigEgg2.Yolk.f()

问题:现在我无法理解这些对象和类是如何初始化的。我觉得命令应该是这样的:

  1. 创建新链接e2: Egg2 e2 =newBigEgg2();
  2. 转到构造函数: public BigEgg2() {insertYolk(insertYolk());}
  3. 由于继承编译器转到: public Yolk() { System.out.println("Egg2.Yolk()");}之后,我们看到了输出: Egg2.Yolk();
  4. 然后编译器调用此方法: public void insertYolk(Yolk ){y= yy;},其中Egg2.Yolk.y = BigEgg2.Yolk.yy (象征性地说)。
  5. 在这个步骤中,我不知道为什么下一个输出结果是: 新Egg2() Egg2.Yolk() BigEgg2.Yolk

这个阶段的外表是什么?

为什么会这样?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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()时,您正在调用BigEgg2Egg2继承的g()方法,该方法调用y.f(),其中y是一个Egg2.Yolk。由于多态性的原因,f()方法在BigEgg2.Yolk中被调用。这是输出BigEgg2.Yolk.f()的第五行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55622308

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档