Java中的继承 - 创建子类的对象也会调用超类的构造函数.为什么呢?

use*_*155 23 java inheritance constructor subclass

我有一个关于Java继承的问题.

我有两个班A,并B和B类,继承自答:

public class A {
     public A() {
         System.out.println("Hi!");
     }
}


public class B extends A {
     public B() {
         System.out.println("Bye!");
     }

     public static void main(String[] args) {
         B b = new B();
     }
}
Run Code Online (Sandbox Code Playgroud)

当我运行程序B时,输出是:

Hi!
Bye!
Run Code Online (Sandbox Code Playgroud)

:为什么构造函数class A调用,当我创建和对象的class B

我知道B继承了A - 所有实例或类变量以及所有方法的所有内容,在这个意义上,B的对象具有A的所有特征以及B中定义的一些其他特征.但是,我不知道并且没有'我想象当我创建一个B类型的对象时,也会调用A的构造函数.所以写下这个:

B b = new B();
Run Code Online (Sandbox Code Playgroud)

创建两个对象 - 一个是B类,另一个是A类.

这很有趣,

有人可以解释为什么会发生这种情况吗?

Kev*_*vin 29

它不会创建两个对象,只有一个:B.

从其他类继承时,必须在构造函数中调用super().如果不这样做,编译器将为您插入该调用,您可以清楚地看到.

调用超类构造函数,因为否则对象将保持未初始化状态,可能是子类开发人员不知道的.

在编译器插入超级调用之后,您的子类实际上看起来像这样:

public class B extends A {
    public B() {
        super();
        System.out.println("Bye!");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为这里的根本误解是对super()的调用是否正在创建一个新对象.事实并非如此. (7认同)

Out*_*mer 16

它不会创建2个对象,它只创建一个B实例.调用超类构造函数的原因是,正如你所说,B具有A的所有字段,并且这些字段需要初始化.


Bri*_*sen 6

记住继承是基类和子类之间的"是一种"关系,因此每次有子类的实例时,根据定义,您还将拥有基类的实例(作为实例的一部分,而不是两个单独的实例).要正确初始化基类,将调用构造函数.

另外,考虑如果子类依赖于基类的某些内部状态会发生什么.您不希望初始化基类的实例吗?