圖解Java繼承內(nèi)存分配
繼承的基本概念:
(1)Java不支持多繼承,也就是說子類至多只能有一個(gè)父類。
(2)子類繼承了其父類中不是私有的成員變量和成員方法,作為自己的成員變量和方法。
(3)子類中定義的成員變量和父類中定義的成員變量相同時(shí),則父類中的成員變量不能被繼承。
(4)子類中定義的成員方法,并且這個(gè)方法的名字返回類型,以及參數(shù)個(gè)數(shù)和類型與父類的某個(gè)成員方法完全相同,則父類的成員方法不能被繼承。
分析以上程序示例,主要疑惑點(diǎn)是“子類繼承父類的成員變量,父類對(duì)象是否會(huì)實(shí)例化?私有成員變量是否會(huì)被繼承?被繼承的成員變量在哪里分配空間?”
1:虛擬機(jī)加載ExtendsDemo類,提取類型信息到方法區(qū)。
2:通過保存在方法區(qū)的字節(jié)碼,虛擬機(jī)開始執(zhí)行main方法,main方法入棧。
3:執(zhí)行main方法的第一條指令,new Student(); 這句話就是給Student實(shí)例對(duì)象分配堆空間。因?yàn)镾tudent繼承Person父類,所以,虛擬機(jī)首先加載Person類到方法區(qū),并在堆中為父類成員變量在子類空間中初始化。然后加載Student類到方法區(qū),為Student類的成員變量分配空間并初始化默認(rèn)值。將Student類的實(shí)例對(duì)象地址賦值給引用變量s。
4:接下來兩條語句為成員變量賦值,由于name跟age是從父類繼承而來,會(huì)被保存在子類父對(duì)象中(見圖中堆中在子類實(shí)例對(duì)象中為父類成員變量分配了空間并保存了父類的引用,并沒有實(shí)例化父類。),所以就根據(jù)引用變量s持有的引用找到堆中的對(duì)象(子類對(duì)象),然后給name跟age賦值。
4:調(diào)用say()方法,通過引用變量s持有的引用找到堆中的實(shí)例對(duì)象,通過實(shí)例對(duì)象持有的本類在方法區(qū)的引用,找到本類的類型信息,定位到say()方法。say()方法入棧。開始執(zhí)行say()方法中的字節(jié)碼。
5:say()方法執(zhí)行完畢,say方法出棧,程序回到main方法,main方法執(zhí)行完畢出棧,主線程消亡,虛擬機(jī)實(shí)例消亡,程序結(jié)束。
總結(jié):相同的方法會(huì)被重寫,變量沒有重寫之說,如果子類聲明了跟父類一樣的變量,那意味著子類將有兩個(gè)相同名稱的變量。一個(gè)存放在子類實(shí)例對(duì)象中,一個(gè)存放在父類子對(duì)象中。父類的private變量,也會(huì)被繼承并且初始化在子類父對(duì)象中,只不過對(duì)外不可見。
super關(guān)鍵字在java中的作用是使被屏蔽的成員變量或者成員方法變?yōu)榭梢姡蛘哒f用來引用被屏蔽的成員變量或成員方法,super只是記錄在對(duì)象內(nèi)部的父類特征(屬性和方法)的一個(gè)引用。啥叫被屏蔽的成員變量或成員方法?就是被子類重寫了的方法和定義了跟父類相同的成員變量,由于不能被繼承,所以就稱作被屏蔽。
說到這里,上面提出的疑惑也就解開了。
本文轉(zhuǎn)載自:http://blog.csdn.net/thinking_in_android/article/details/8874171
相關(guān)鏈接:
圖解Java對(duì)象初始化過程以及方法調(diào)用
posted on 2013-05-10 09:27 順其自然EVO 閱讀(203) 評(píng)論(0) 編輯 收藏