继承中多态的内存分配






class Fu
{
	int num = 40;

	void show()
	{
		System.out.println("show Fu");
	}

}

class Zi extends Fu
{
	int num = 20; 

	void show()
	{
		System.out.println("show Zi");
	}

	void method()
	{
		System.out.println("method Zi");
	}
}

class Text 
{
	public static void main(String[] args) 
	{
		Fu fu = new Zi();

		System.out.println(fu.num);

		fu.show();
		fu.method();
	}
}


1、首先判断方法区里面的class文件区有多少个class文件,我这里有Fu.class,Zi.class,Text.class。
2、静态随着类的加载而加载,然后再判断方法区里面的静态方法区里面有什么方法,我这里只有main方法
3、然后main方法进栈,处于高地址(也就是最下面)
4、main方法里面有一个引用,名为fu的Fu变量,但开辟的是Zi的空间,于是堆内存就开辟了一个new Zi()的空间
5、我们可以这样想,其实 new Zi() 空间里面包含着两个空间,一个空间用this来标记,一个用super来标记;
6、标记着子类空间的用this来表示,标记父类空间的用super来表示。
7、子继承类的时候,是先对父类进行初始化,开始父类声明了个值为40的num变量(在堆中产生),父类里面又有个show(),把方法放在Fu类的方法区中,Fu类方法区的地址给了super,从而super可以访问Fu类方法区的方法,super空间才初始化完毕
8、这时候,super空间与Fu类方法区有了一定的关联,但没有去访问。
9、父类初始化完毕,就去初始化子类
10、首先Zi类有个值为20的num变量(在堆中产生),然后再加载show方法和method(在Zi类方法区中产生)。
11、然后Zi类方法区的地址给了this,从而this可以访问Zi类方法区的方法,this空间也就初始化完成
12、这时候,this空间与Zi类方法区有了一定的关联,但也同样没有去访问。
13、new Zi()空间初始化完毕之后,把地址给了fu的Fu类变量,然后fu也就指向new Zi ()。
14、然后补充一点:成员变量仅仅是该事物的外在特征描述,而成员方法是该事物的功能描述(内在特征描述)。
15、所以,当fu.num执行的时候,调用的是该类的外在特征描述,fu是代表父类的,所以也就是调用super空间的num;
外在特征的意思也就是,你本来是哪个类的对象,就调用哪个类的成员变量。
16、也所以,当fu.show()执行的时候,虚拟机会看看Fu类方法区中是否有show(),如果有,就看看有没被重写,没有被重写,就执行Fu方法区的show();如果有被重写,就调用子类的show()。如果Fu类中没有show(),就算子类有show(),编译也报错,更谈不上执行。
17、遇到多态的时候,简单总结一句话:编译看左边,运行看右边。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值