一、查询网上的结论:
创建子类对象时, 会先调用子类构造方法对子类对象进行初始化,子类构造方法的第一行又会调用父类构造方法对父类进行初始化(不会创建父类对象, 但是会在子类对象的内存空间中开辟一块被包含的内存空间存储父类的信息,包括私有成员变量和非私有成员变量<私有成员变量子类对象无法直接用super访问>)。 有些文章也会将 "在子类对象的内存空间中开辟一块被包含的内存空间存储父类的信息" 理解成一个父类的伪对象或亚对象(和父类创建的对象结构相同,但不是真正的父类对象, 子类对象可以使用这个父类的亚对象调用父类的成员变量和成员方法, super就代表这个亚对象)
下边案例演示了: 子类访问父类的私有成员变量及成员变量的初始化过程
package cn.zyq.charging.order;class Father{//父类成员变量初始化过程private int age=1;//1.先给age分配空间并分配默认的值0, 然后执行手动的赋值语句赋值为1{//2.然后执行非静态代码块将age赋值为2age=2;}Father(){//3.再调用构造方法将age赋值为3age=3;}//子类的age初始化过程也是这样的public int getAge(){return age;}
}class Child extends Father {private int age=10;{age=20;}Child(){super();age=30;System.out.println(super.getAge());System.out.println(this.age);}}public class Test {public static void main(String[] args) {new Child();}
}
二、静态代码块和非静态代码块的执行顺序:
package cn.zyq.charging.order;
class Father{Father(){System.out.println("4.父类构造");}{System.out.println("3.父类代码块");}static{System.out.println("1.父类静态代码块");}
}class Child extends Father {private int age=10;static{System.out.println("2.子类静态代码块");}Child(){System.out.println("6.子类构造");}{System.out.println("5.子类代码块");}
}public class Test {public static void main(String[] args) {new Child();}
}
结果:
1.父类静态代码块
2.子类静态代码块
3.父类代码块
4.父类构造
5.子类代码块
6.子类构造