在java中的多层次继承中的构造函数调用顺序 [英] order of constructor calls in multilevel inheritance in java

查看:246
本文介绍了在java中的多层次继承中的构造函数调用顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

//: c07:Sandwich.java
// Order of constructor calls.
// package c07;
// import com.bruceeckel.simpletest.*;

import java.util.*;

class Meal {
  Meal() { System.out.println("Meal()"); }
}

class Bread {
  Bread() { System.out.println("Bread()"); }
}

class Cheese {
  Cheese() { System.out.println("Cheese()"); }
}

class Lettuce {
  Lettuce() { System.out.println("Lettuce()"); }
}

class Lunch extends Meal {
  Lunch() { System.out.println("Lunch()"); }
}

class PortableLunch extends Lunch {
  PortableLunch() { System.out.println("PortableLunch()");}
}

public class Sandwich extends PortableLunch {
//  private static Test monitor = new Test();
  private Bread b = new Bread();
  private Cheese c = new Cheese();
  private Lettuce l = new Lettuce();
  public Sandwich() {
    System.out.println("Sandwich()");
  }
  public static void main(String[] args) {
    new Sandwich();
   /*
   monitor.expect(new String[] {
      "Meal()",
      "Lunch()",
      "PortableLunch()",
      "Bread()",
      "Cheese()",
      "Lettuce()",
      "Sandwich()"
    });
    // */
  }
} ///:~

此代码的输出为

Meal()
Lunch()
PortableLunch()
Bread()
Cheese()
Lettuce()
Sandwich()  


b $ b

由于类中的字段是按声明的顺序创建的,为什么不

Since the fields in a class are created in the order they are declared, why don't

Bread()
Cheese()
Lettuce()

上面的列表?

此外,在此代码中尝试做什么?

Also, what is it trying to do in this code?

   monitor.expect(new String[] {
      "Meal()",
      "Lunch()",
      "PortableLunch()",
      "Bread()",
      "Cheese()",
      "Lettuce()",
      "Sandwich()"
    });  

起初我以为这是一个匿名类,但它看起来不像。是否正在初始化一个字符串数组?为什么它没有String变量的名称?请告诉我这里使用的编程结构的名称。

At first I thought it was an anonymous class, but it doesn't look like it. Is it initializing a String array? Why doesn't it have the name for the String variable? Please tell me the name of the programming construct being used here.

推荐答案

构造函数:

public Sandwich() {
    System.out.println("Sandwich()");
}

由编译器翻译为:

public Sandwich() {
    super();   // Compiler adds it if it is not explicitly added by programmer
    // All the instance variable initialization is moved here by the compiler.
    b = new Bread();
    c = new Cheese();
    l = new Lettuce();

    System.out.println("Sandwich()");
}



因此,构造函数中的第一个语句是超类构造函数的链接。事实上,任何构造函数中的第一个语句链接到超类构造函数,就是这样。这就是为什么首先调用超类构造函数 PortableLunch ,它再次链接对它的超类构造函数的调用,由于 super )

So, the first statement in a constructor is the chaining of super class constructor. In fact, the first statement in any constructor chains to the super class constructor, for that matter. That is why first the super class constructor PortableLunch is invoked, which again chains the call to it's super class constructor, due to the super() added by the compiler (remember?).

这个链接的构造函数调用完成,直到顶部的类继承层次结构,从而调用 Object 类构造函数。

This chaining of constructor call is done till the class at the top of the inheritance hierarchy, thereby invoking the Object class constructor at the end.

现在,已经执行,并且所有的超类字段已经被初始化,直接子类构造函数在 super()调用之后开始执行。最后,它返回到 Sandwitch()构造函数,现在将初始化您的 3 字段。

Now, after each the super class constructor has been executed, and all the super class fields have been initialized, the immediate subclass constructor start the execution after the super() call. And then finally it comes back to the Sandwitch() constructor, which now initializes your 3 fields.

因此,基本上你的字段最后被初始化,因此它们被打印在结尾,就在 Sandwitch()

So, basically your fields are initialized at last, and hence they are printed at the end, just before Sandwitch() is printed.

请参阅 JLS - §12.5 - 创建新类实例 ,以了解实例创建过程的详细解释。

Refer to JLS - §12.5 - Creation of New Class Instance for detailed explanation of the instance creation process.

至于问题的第二部分:

monitor.expect(new String[] {
      "Meal()",
      "Lunch()",
      "PortableLunch()",
      "Bread()",
      "Cheese()",
      "Lettuce()",
      "Sandwich()"
    });  

此代码正在创建未命名的数组,并初始化一些字符串与此同时。它类似于创建命名数组的方式:

This code is creating an unnamed array, and initializing it some string literals at the same time. It is similar to the way you would create a named array:

String[] arr = new String[] { "rohit", "jain" };

这篇关于在java中的多层次继承中的构造函数调用顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆