1. 程式人生 > >java中父類子類的成員變數和成員方法在記憶體分配上的一些理解

java中父類子類的成員變數和成員方法在記憶體分配上的一些理解

先宣告,以下是個人自己的理解(我也怕誤人子弟),如有錯誤請指出一起學習交流。

先上程式碼:

package myTest;

class A {
	int num = 5;

	A() {
		show();
	}

	public void show() {
		System.out.println("A" + num);
	}
}

class B extends A {
	int num = 10;

	B() {
		show();
	}

	public void show() {
		 System.out.println("B"+num);
		//super.show();
	}
}

public class Test01 {
	public static void main(String[] args) {
		B b = new B();
	}
}

以上程式碼輸出:

B0

B10

個人理解:在new B()的時候,肯定先在B的堆區中構造父類的例項,按照順序是 :父類的成員變數num,並賦值等於5-> 父類的無參建構函式(若指定建構函式另說) -> 子類的成員變數並賦值 -> 子類的建構函式,這個順序,所以B的堆區中有兩部分,一部分是this區域,代表B繼承過來的變數和方法,還有一部分是super區域,代表父類的變數和方法。

所以,在new B()的時候,先執行父類的建構函式,由於程式會給每一個方法隱藏傳入this變數,所以這裡的this變數肯定是B,由於B重寫的show()方法,所以呼叫B的show()方法,因為在執行父類建構函式的時候,B的num還沒有初始化,所以是0。然後初始化B的num,再執行B的構造方法,此時也是呼叫B的show(),並且此時num的值已經是10。

注意:如果B類不重寫A類的show(),那麼B的堆區this區域中也沒有執行show()程式碼區的地址,所以此時this找不到show()會自動去找super區域的show(),這種情況會輸出A5。變數沒有重寫之說,繼承過來的變數都會在B的this區域分配記憶體,就算B中沒有為num賦值,在B的this區域還會為num分記憶體。若A有私有變數,會在B的堆區的super區域分配記憶體,只是對外不公開,所以被sun公司定義為私有變數不能被繼承(個人猜測)。

大家可以嘗試一下B中不重寫show()和不給num賦值,看看效果就理解了。

請看在記憶體中: