如何理解java继承中内存分布

继承是java面向对象的一大特征,继承是多态的基础。将两个具备共性属性的事物向上抽取,是泛化的过程。在java中,则是相反的继承过程。那么,继承在内存中的特点是怎样的呢?通过下面这段代码,我们来具体分析:
class A {
private int a = 1;
public A() {
println();
}
public void println() {
System.out.println(“A-a:”+a);
}
}
class B extends A{
private int a = 2;
public B() {
println();
}
public void println() {
System.out.println(“B-a:”+a);
}
}
class C extends B{
private int a = 3;
public C() {
println();
}
public void println() {
System.out.println(“C-a:”+a);
}

}
public class TestExtend {

public static void main(String[] args) {

    new C();
}

}
运行结果:
C-a:0
C-a:0
C-a:3

分析,new C( )的执行过程。首先在编译TestExtend类后产生了A、B、C、TestExtend四个class文件,执行java TestExtend后启动jvm,jvm内存方法区中加载进TestExtend.class文件,jvm调用main方法。此时,在栈区中开辟了main方法的栈帧。
加载C类文件进方法区,执行new运算,此时则在堆区开辟内存空间,创建C对象。C对象中包含有父类的属性,并要对父类成员变量进行初始化,要使用到父类构造方法,所以,将A、B类文件都加载进方法区中。
需要对C的直接父类B类成员变量a进行初始化,而B类又需要对其直接父类A类的成员变量a进行初始化,先执行默认初始化动作,此时对象中A类成员变量a为0,后执行显示初始化动作,为1,然后调用构造方法,构造方法中调用println()方法,非静态成员的调用必定要使用到对象,此时A类中构造方法的this指向了调用当前方法的B类对象,即C对象,这其中就有了多态的出现,A类引用指向B类对象。根据动态绑定,此时调用的是C对象的println()方法,此时C类的成员变量a是默认值0,所以输出结果是0。A类成员变量a初始化完成之后,执行B类成员变量a的初始化,同理,输出0。
当B类成员变量a初始化完成之后,最后执行C对象的成员变量初始化,执行显示初始化后a=3,然后执行构造方法,输出a的值为3。

你可能感兴趣的:(javaSe基础,继承)