我们根据下面这段代码来进行解析:
class Fu
{
int num1 = 2;
int num2 = 0;
private int num = 1;
private void show()
{
System.out.println("父类");
}
public int getNum()
{
return num;
}
}
class Zi extends Fu
{
int num1 = 3;
public void show()
{
System.out.println(super.getNum());
}
}
class TestDemo
{
public static void main(String[] args)
{
Zi z = new Zi();
z.num1 = 4;
System.out.println(z.num1);
z.show();
}
}
分析图解如下图所示:
(2)主函数main()入栈,在栈中定义Zi类型的引用z,this,由于Zi有父类,定义一个Fu类型的引用super,这三个引用都初始化为null。
(3)要想给Zi类分配对象,要把其父类Fu放入方法区中,再把本来放入方法区中。
(4)在堆内存中分配一块内存(由new方法得到),由于子类继承了父类的成员变量,所以在该内存块中定义从父类中继承来的变量num2和num2,并初始化为0,我们称这块包含父类成员的内存块为子父类对象。
(5)在该内存块中为子类成员变量分配空间并默认初始化。
(6)调用方法区中子类构造函数Zi(),该函数入栈。在函数体的第一行调用了父类的构造函数Fu(),Fu()入栈对子父类初始化,在进行父类的显示初始化,子父类对象初始化完毕后把地址赋给super。
(7)继续执行下面的构造函数体,构造函数结束后进行子类的显示初始化。
(8)将对象的地址赋给this和z。
(1)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法。
(2)子类中定义的成员变量和父类中定义的成员变量相同时,则父类中的成员变量不能被继承。
(3)子类中定义的成员方法,并且这个方法的名字返回类型,以及参数个数和类型与父类的某个成员方法完全相同,则父类的成员方法不能被继承。