我有一个关于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(); } }
当我运行程序B时,输出是:
Hi! Bye!
问:为什么构造函数的
class A
调用,当我创建和对象的class B
?
我知道B继承了A - 所有实例或类变量以及所有方法的所有内容,在这个意义上,B的对象具有A的所有特征以及B中定义的一些其他特征.但是,我不知道并且没有'我想象当我创建一个B类型的对象时,也会调用A的构造函数.所以写下这个:
B b = new B();
创建两个对象 - 一个是B类,另一个是A类.
这很有趣,
有人可以解释为什么会发生这种情况吗?
它不会创建两个对象,只有一个:B.
从其他类继承时,必须在构造函数中调用super().如果不这样做,编译器将为您插入该调用,您可以清楚地看到.
调用超类构造函数,因为否则对象将保持未初始化状态,可能是子类开发人员不知道的.
在编译器插入超级调用之后,您的子类实际上看起来像这样:
public class B extends A { public B() { super(); System.out.println("Bye!"); } }
它不会创建2个对象,它只创建一个B实例.调用超类构造函数的原因是,正如你所说,B具有A的所有字段,并且这些字段需要初始化.
记住继承是基类和子类之间的"是一种"关系,因此每次有子类的实例时,根据定义,您还将拥有基类的实例(作为实例的一部分,而不是两个单独的实例).要正确初始化基类,将调用构造函数.
另外,考虑如果子类依赖于基类的某些内部状态会发生什么.您不希望初始化基类的实例吗?