关于派生类构造器对基类构造器的调用

本文探讨了Java中派生类构造器如何调用基类构造器的细节,包括默认构造器与带参数构造器的不同行为,以及初始化顺序对构造过程的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

其实这将是"《JAVA编程思想》第四版学习 需要我记住的something -复用类"的一部分,之所以单独提出来,并提前发出来,只是要增强自己的记忆吧。

 

      Java自动在派生类构造器中插入调用基类构造器的代码,即使未定义派生类构造器,编译器仍会产生一个默认构造器来调用基类构造器,而且基类构造器调用发生在派生类构造器之前。
      那么,是不是可以认为基类构造器调用是派生类构造器的第一条语句,从而在派生类构造器调用的时候才调用呢?不是。请看这个代码:

      按照初始化顺序,那么定义时的初始化发生在构造器之前,也就是b的赋值应该发生在C的默认构造器之前,如果基类构造器调用是派生类构造器的第一条语句,从而在派生类构造器调用的时候才调用,那运行结果应该是
B constructor
A constructor
而实际结果是
A constructor
B constructor
      显然,"基类构造器调用是派生类构造器的第一条语句,从而在派生类构造器调用的时候才调用"这个说法是错误的。应该是:基类的初始化发生在派生类的初始化(包括自动初始化、构造器等等)之前。

 

       前面说的是无参构造器(默认构造器),对于有参数的构造器:
      1. 如果基类构造器都有参数,必须显式调用基类构造器(super(...))(如果不,编译器报错,找不到基类默认构造器),而且必须是派生类构造器的第一条语句(如果不,编译器报错,找不到基类默认构造器和super调用必须是第一条语句两个错误)。
      2. 如果基类构造器没有参数,则不需显式调用,编译器会为你完成。
      3. 如果派生类有多个构造器,在基类构造器有参数的时候,你显然得在所有派生类构造器中加入super(...);如果基类构造器没有参数,编译器会在所有派生类构造器内加入对基类构造器的调用(因为编译器不知道你会调用哪个构造器,对吧?嘿嘿)。
看例子

结果:
A constructor
B constructor
B constructor
C(int i) constructor
A constructor
B constructor
C() constructor

 

       在显式调用的情况下,似乎上面的讨论又是错的,基类构造器调用就是派生类构造器的第一条语句,在派生类构造器调用的时候才调用。结果呢?再次证明这句话是错的。你仍然得说:基类的初始化发生在派生类的初始化(包括自动初始化、构造器等等)之前。看这个例子:

A constructor
B constructor
B constructor
C constructor
结果说明了一切,虽然你super(i)是在派生类构造器的第一条语句。

 

       总之一句话,未显式调用基类构造器的情况下,编译器就查找基类的默认构造器,找不到报错;找到,加入对它的调用。基类没有默认构造器,就必须显式调用。基类的初始化发生在派生类的初始化(包括自动初始化、构造器等等)之前。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值