7

我是初学者,目前正在阅读继承和多态性。我对关键字“extend”和构造函数的调用方式有些困惑。这是代码:

public class Test {
  public static void main(String[] args) {
    new B();
  }
}

class A {
  int i = 7;

  public A() {
    System.out.println("i from A is " + i);
  }

  public void setI(int i) {
    this.i = 2 * i;
  }
}

class B extends A {
  public B() {
    setI(20);
    System.out.println("i from B is " + i);
  }

  public void setI(int i) {
    this.i = 3 * i;
  }
}

我知道通过在第 3 行调用 B(),调用 A 类的构造函数,然后调用 B 的构造函数(对吗?),因此它显示“来自 A 的 i 为 7”,然后显示“来自 B 的 i 为 60”。但是有人能解释一下这件事的重要性吗?为什么 B 中的 int i 与 A 中的 in i 完全不同?同样,我在新 B() 行之后无法遵循代码的“路径”。如果有人可以在调用 B() 后解释每个步骤,那将不胜感激。

4

5 回答 5

10

我在新 B() 行之后无法遵循代码的“路径”。如果有人可以在调用 B() 后解释每个步骤,那将不胜感激。

调用时new B(),从技术上讲,流程首先进入构造函数B()。Java 中的构造函数总是需要(最终)链接到更高的构造函数(递归地直到达到最高类 , Object)。链接由super(...)orthis(...)语句表示为构造函数的第一条语句。如果没有明确写入,super()则假定为无参数。所以,B()实际上编译就好像它是这样写的:

  public B() {
    super();
    setI(20);
    System.out.println("i from B is " + i);
  }

现在您可以清楚地看到new B()调用B()了哪些调用A()(调用println并退出),然后是setI最后println

为什么 B 中的 int i 与 A 中的 in i 完全不同?

i是完全相同的字段。不同之处在于您setI(20)在两个打印输出之间调用,从而改变了i. 如果您删除对 的调用setI,您将看到该值仍然存在7

于 2013-09-11T22:02:18.530 回答
1

当您创建 B 的实例并调用构造函数 B() 时,它将首先调用super(),在您的情况下将调用A()

这将打印i from A is 7,因为 7 是您设置的默认值i

在调用 super 之后,它会移动到下一行,即setI(20). 此行将iin B 设置为 60,因为您的setI(int i)方法将参数 (20) 乘以 3,然后设置i为该值。

然后,您正在打印i from B is 60,因为i现在是 60。

于 2013-09-11T21:59:16.783 回答
1

Java 语言规范说

如果构造函数体不是以显式构造函数调用开始,并且被声明的构造函数不是原始类 Object 的一部分,则构造函数体隐式以超类构造函数调用“super();”开始,调用它的直接超类不带参数。

这意味着当你写的时候new B(),构造函数做的第一件事B就是调用构造函数A。在 for 的构造函数A设置i为 7 后,B调用的构造函数setI(20)将 的值更改i为 60。只有一个- in和 ini没有区别。它只是在一个和下一个之间改变了值。ABprintln

于 2013-09-11T22:07:07.983 回答
0

子类必须始终通过 super() 或通过使用 super 和该构造函数的参数调用另一个构造函数来调用其超类的构造函数。

如果您不显式添加 super(),Java 将在幕后为您完成。

class B extends A {

}

与调用相同:

class B extends A {
    public B() {
        super();
    }
}

知道了这一点,显然调用new B();将调用 B 构造函数,然后在完成之前调用 A 构造函数。

于 2013-09-11T21:59:15.157 回答
0

当您调用 to 时new B(),VM 隐式调用 super(),然后一个新的 A() 正在写入 7,但是在您的 setI 中您正在覆盖该方法,这是因为您看到了 60。

使用注释@Override 总是一个好主意。

BR

于 2013-09-11T22:09:03.657 回答