Java中的继承机制看似简单,实际上包含了很多细节。最近在刷题过程中屡屡跳坑,于是自己仔细再学习了一下Java中子类初始化的细节,与大家分享。
class Father { Father(){}; } class Child extends Father
{ super(); //隐式地调用父类构造函数,对父类进行初始化
int age = 10;
Child(){};
}
以以上代码为例:
若执行Child child = new Child();
(1)首先对子类变量进行初始化(int age=0);
(2)执行子类Child构造函数中的隐式super(),调用父类构造函数对父类进行初始化;
(3)执行子类Child构造函数中的其余部分,对子类进行初始化;
(4)对子类变量进行初始化(child.age = 10)
下面我们用一个例子,结合多态来详细说明该初始化过程:
class Father { Father() { show(); } void show() { System.out.println("father"); } } class Child extends Father { int age = 9; Child() { //隐式super(); System.out.println("child"+age); } void show() { System.out.println("show"+age); } } public class ChuShiHua { public static void main(String[] args) { Father child = new Child(); } }
(1)执行Child child = new Child();时:首先默认初始化child.age = 0;(int类的默认初始化值为0)(2)执行Child类的构造器,首先执行其中的隐式super(),于是执行父类Father的构造器,执行函数体中的show()’
(3)因为多态机制,子类中也有show(),所以执行子类中的show(),输出show0
(4)父类初始化完毕,接着对子类中的变量赋值(child.age=9)
(5)接着执行子类构造器中的语句,输出child9
所以最后的输出是:
show0
child9
在分析此类问题时要特别注意子类在执行构造器时会先执行一个隐式的super()
这意味着子类调用构造器时要先执行父类的无参数构造器对父类进行初始化,如果父类没有无参构造器,则会出现如下编译错误: