继承中子父类成员变量的内存图解:
1, 划分栈,堆,方法区,空间。主函数进栈,变量z出现(如图1)。
2, 由于子类继承父类,子类要使用父类,父类需先进方法区。先加载父类,再加载子类(如图2)。
3, 接着开始执行newZi(),在堆里创建对象,划分空间地址(如图3)。
4, 子类继承了父类,父类是存储在子类里面的。这个时候子类一继承父类,父类变量就到了子类里面(如图4)。
5, 初始化完毕后,将0x0045赋给了z,z就指向了对象(如图5)。
6, 接着执行z.show(),show方法进栈,show里面有this,this拥有所属对象的地址值0x0045。
继续执行show里的方法,this.num,super.num。子类加载完成了有一个父类的引用super。
7.show弹栈,main弹栈。
一个对象实例化过程:
Person p = new Person();
1,JVM会读取指定的路径下的Person.class文件,并加载进内存,并会先加载Person的父类(如果有直接的父类的情况下)。
2,在堆内存中的开辟空间,分配地址。
3,并在对象空间中,对对象中的属性进行默认初始化。
4,调用对应的构造函数进行初始化。
5,在构造函数中,第一行会先到调用父类中构造函数进行初始化。
6,父类初始化完毕后,在对子类的属性进行显示初始化。
7,在进行子类构造函数的特定初始化。
8,初始化完毕后,将地址值赋值给引用变量。
class Father {
int age = 50;
Father() {
super();
say();
return;
}
void say() {
System.out.println("爸爸");
}
}
class Son extends Father {
int age = 20;
Son() {
super();
//-->通过super初始化父类内容时,子类的成员变量并未显示初始化。等super()父类初始化完毕后,
//才进行子类的成员变量显示初始化。
say();
return;
}
void say() {
System.out.println("爸爸" + super.age + "岁");
System.out.println("儿子" + this.age + "岁");
}
}
class Test {
public static void main(String[] args) {
Son s = new Son();
// s.say();
}
}
执行结果:
爸爸50岁
儿子0岁
爸爸50岁
儿子20岁
重点:
通过super初始化父类内容时,子类的成员变量并未显示初始化。等super()父类初始化完毕后,才进行子类的成员变量显示初始化。