首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >java中多级继承中构造函数调用的顺序

java中多级继承中构造函数调用的顺序
EN

Stack Overflow用户
提问于 2013-07-23 17:27:09
回答 2查看 31.2K关注 0票数 21
代码语言:javascript
复制
//: 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()"
    });
    // */
  }
} ///:~

这段代码的输出是

代码语言:javascript
复制
Meal()
Lunch()
PortableLunch()
Bread()
Cheese()
Lettuce()
Sandwich()  

既然类中的字段是按照声明的顺序创建的,为什么不

代码语言:javascript
复制
Bread()
Cheese()
Lettuce()

排在上述列表的首位?

另外,它试图在这段代码中做什么?

代码语言:javascript
复制
   monitor.expect(new String[] {
      "Meal()",
      "Lunch()",
      "PortableLunch()",
      "Bread()",
      "Cheese()",
      "Lettuce()",
      "Sandwich()"
    });  

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

EN

回答 2

Stack Overflow用户

发布于 2013-07-23 17:30:33

示例中的对象使用继承,这会导致调用一系列构造函数。在使用继承时,从另一个(subtype)继承的类必须调用它扩展的类(super type)的构造函数。当存在类型层次结构时,意味着多个类在链中彼此延伸,对超级构造函数的调用将传播到链中不从另一个类继承的第一个类(忽略Object)。

子类型的超类构造函数必须在执行子类型的构造函数之前调用,因为它可能依赖于超类型中的字段或方法。构造函数调用类型层次结构,一旦每个构造函数初始化,子类型就开始实例化。

一旦类类型层次结构中的超类型构造函数被调用,子类型的字段就会被声明,因为子类型的构造函数也可能需要它们。子类型的字段声明之后,子类型构造函数就会执行。

这个顺序是必要的,因为子类型可能依赖于在超类型中建立的字段或方法。

代码语言:javascript
复制
Meal() (Top of Class Hierarchy, not including Object)
Lunch() (Extends Meal)
PortableLunch() (Extends Lunch)
Bread() (Field of lunch declared before constructor call)
Cheese() (Field of lunch declared before constructor call)
Lettuce() (Field of lunch declared before constructor call)
Sandwich() (Extends Portable Lunch)

Here is a really good overview of object creation in Java.

票数 5
EN

Stack Overflow用户

发布于 2013-07-23 17:32:32

首先调用构造函数,然后根据Java Language Specification中指定的顺序计算其实例变量。这就是为什么你会

代码语言:javascript
复制
Bread()
Cheese()
Lettuce()

之后

代码语言:javascript
复制
Meal()
Lunch()
PortableLunch()

关于String[]初始化,因为你认为它不是一个匿名类,它只是一个字符串对象的创建,它不需要被赋值给变量。

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

https://stackoverflow.com/questions/17806342

复制
相关文章

相似问题

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