package pg1;
class A{
public A() {
System.out.println("1");
}
}
class B extends A{
public B() {
System.out.println("2");
}
public B(String name) {
//super();
System.out.println("3");
}
}
class C extends B{
public C() {
this("zhanghao"); //调用有参构造方法
System.out.println("4");
}
public C(String name) {
this(name,20);
System.out.println("5");
}
public C(String name,int age) {
super(name); //调用B父类有参方法
System.out.println("6");
}
}
public class Test {
public static void main(String[] args) {
new C(); //倒着进行
}
}
//运行结果1 3 6 5 4
按照常规逻辑,调用构造方法,输出的语句是按继承链依次进行,但在程序执行时,一定会从儿子到父亲再到爷爷进行,即逆着继承链进行。
因此若在Test主方法中创建对象,则会先调用C中的方法1,之后C的方法2,C的方法3,之后super关键字,B的有参构造方法,因为B也是一个子类构造方法,因此B的有参构造方法中(因为C中调用了B的有参构造方法).
编译器会自动在B的有参构造方法的第一行添加super(由于this和super关键字不能共用,因此B的有参构造方法并不会调用B无参构造方法),调用了A的构造方法。
我们换一种思路,看看B的有参构造方法中super()是否被添加
package pg1;
class A{
public A() {
System.out.println("1");
}
public A(int age) { //添加了一个有参构造方法
System.out.println("X");
}
}
class B extends A{
public B() {
System.out.println("2");
}
public B(String name) {
super(1); //添加了super(参数)的语句,调用了A的有参构造方法
System.out.println("3"); //结果得到了X
//未添加语句的结果为1 3 6 5 4
//总体输出结果为X 3 6 5 4
//说明编译器会在未添加super关键字的位置添加一个 //无参构造方法,只不过被我们的super(1)覆盖了
}
class C extends B{
public C() {
this("zhanghao"); //调用有参构造方法
System.out.println("4");
}
public C(String name) {
this(name,20);
System.out.println("5");
}
public C(String name,int age) {
super(name); //调用B父类有参方法
System.out.println("6");
}
}
public class ASD {
public static void main(String[] args) {
new C(); //倒着进行
}
}