1. 程式人生 > >圖解Java繼承記憶體分配

圖解Java繼承記憶體分配

繼承的基本概念: (1)Java不支援多繼承,也就是說子類至多隻能有一個父類。 (2)子類繼承了其父類中不是私有的成員變數和成員方法,作為自己的成員變數和方法。
(3)子類中定義的成員變數和父類中定義的成員變數相同時,則父類中的成員變數不能被繼承。
(4)子類中定義的成員方法,並且這個方法的名字返回型別,以及引數個數和型別與父類的某個成員方法完全相同,則父類的成員方法不能被繼承。
分析以上程式示例,主要疑惑點是“子類繼承父類的成員變數,父類物件是否會例項化?私有成員變數是否會被繼承?被繼承的成員變數在哪裡分配空間?” 1:虛擬機器載入ExtendsDemo類,提取型別資訊到方法區。 2:通過儲存在方法區的位元組碼,虛擬機器開始執行main方法,main方法入棧。 3:執行main方法的第一條指令,new Student(); 這句話就是給Student例項物件分配堆空間。因為Student繼承Person父類,所以,虛擬機器首先載入Person類到方法區,並在堆中為父類成員變數在子類空間中初始化。然後載入Student類到方法區,為Student類的成員變數分配空間並初始化預設值。將Student類的例項物件地址賦值給引用變數s。 4:接下來兩條語句為成員變數賦值,由於name跟age是從父類繼承而來,會被儲存在子類父物件中(見圖中堆中在子類例項物件中為父類成員變數分配了空間並儲存了父類的引用,並沒有例項化父類。),所以就根據引用變數s持有的引用找到堆中的物件(子類物件),然後給name跟age賦值。 4:呼叫say()方法,通過引用變數s持有的引用找到堆中的例項物件,通過例項物件持有的本類在方法區的引用,找到本類的型別資訊,定位到say()方法。say()方法入棧。開始執行say()方法中的位元組碼。 5:say()方法執行完畢,say方法出棧,程式回到main方法,main方法執行完畢出棧,主執行緒消亡,虛擬機器例項消亡,程式結束。 總結:相同的方法會被重寫,變數沒有重寫之說,如果子類聲明瞭跟父類一樣的變數,那意味著子類將有兩個相同名稱的變數。一個存放在子類例項物件中,一個存放在父類子物件中。父類的private變數,也會被繼承並且初始化在子類父物件中,只不過對外不可見。 super關鍵字在java中的作用是使被遮蔽的成員變數或者成員方法變為可見,或者說用來引用被遮蔽的成員變數或成員方法,super只是記錄在物件內部的父類特徵(屬性和方法)的一個引用。啥叫被遮蔽的成員變數或成員方法?就是被子類重寫了的方法和定義了跟父類相同的成員變數,由於不能被繼承,所以就稱作被遮蔽。 說到這裡,上面提出的疑惑也就解開了。