Java關於繼承中的轉型及其記憶體分配

鴨脖發表於2012-10-06

java 子類例項化時是否同時存在一個父類物件.

  2011-10-14 19:53
提問者: luoyuehao89 | 瀏覽次數:602次
java 子類例項化時是否同時存在一個父類物件.
假如父類A中有個int a = 1;
子類B繼承A,同時B中覆蓋個int a = 2;

執行:
A test = new B();
system.out.println(test.a);

結果是1,是父類中的屬性.這個時候是否存在父類物件,我的理解是存在的.
我又試,把父類用抽象abstract修飾,按理說abstract累不能例項化吧,肯定不能得到父類中的a屬性,結果還是一樣的.
怎麼理解.

問題補充:

是不是建立子類物件,肯定會出現一個父類的物件?

我來幫他解答
檢舉 | 2011-10-22 16:33
精彩回答
不會產生父類物件,只是用了父類的建構函式而已,並不是用到建構函式就會產生物件,建構函式只是起物件初始化作用的,而不是起產生物件作用的,如果new A();即只有new語句才會產生父類A的物件。


變數是靜態繫結 ,方法是動態繫結。 這裡面變數在編譯期間實現了變數呼叫語句與變數定義賦值語句的繫結,繫結的自然是父類的,因為呼叫時型別是父類的,所以值是父類中定義的值 

其實你可以這麼理解  建立了一個子類物件時,在子類物件記憶體中,有兩份這個變數,一份繼承自父類,一份子類。 
絕對不會產生父類物件,父類中的成員被繼承到子類物件中,用指向子類物件的父類引用呼叫父類成員,只不過是從 子類物件記憶體空間中找到那個被繼承來的父類成員,也就是說實質是用子類物件呼叫變數a,這樣就可以解釋成員必須通過物件呼叫的規定,只不過這時呼叫的是子類物件中的繼承自父類的a(子類物件中有兩個a,一個繼承自父類,一個屬於自己)


哎,話說的有些亂。  這個問題也困惑我很久,上網查詢發現很多人是錯誤的,最後找到幾篇好的文章才明白,可能很多java老手也都會犯“產生父類物件”這個錯誤,最近才搞明白。

你自己想想,如果產生父類物件,如果父類是抽象類,抽象類允許產生物件嗎?所以這種說法不嚴謹






package jc.cn;
public class Car
{
   public int a;
   public int b;
}
class Truck extends Car
{
   byte c;
   byte d;
}
class Smp
{
   public static void main(String[] args)
   {
      Truck t=new Truck();
   }
}

當執行完下句後:
Truck t=new Truck();

求物件的記憶體模型圖?
我來幫他解答
檢舉 | 2009-11-17 07:55
滿意回答

左邊是棧空間,右邊是堆空間,棧空間的變數t儲存著一個指向堆空間某個物件的地址

動態繫結定義

  動態繫結是指在執行期間(非編譯期)判斷所引用物件的實際型別,根據其實際的型別呼叫其相應的方法

編輯本段靜態繫結與動態繫結

  除了限制訪問,訪問方式也決定哪個方法將被子類呼叫或哪個屬性將被子類訪問. 函式呼叫與函式本身的關聯,以及成員訪問與變數記憶體地址間的關係,稱為繫結. 在計算機語言中有兩種主要的繫結方式,靜態繫結和動態繫結. 靜態繫結發生於資料結構和資料結構間,程式執行之前. 靜態繫結發生於編譯期, 因此不能利用任何執行期的資訊. 它針對函式呼叫與函式的主體,或變數與記憶體中的區塊.. 動態繫結則針對執行期產生的訪問請求,只用到執行期的可用資訊. 在物件導向的程式碼中,動態繫結意味著決定哪個方法被呼叫或哪個屬性被訪問,將基於這個類本身而不基於訪問範圍.

相關文章