如何理解父類引用指向子類物件

2021-08-21 10:38:27 字數 2627 閱讀 5340

從物件的記憶體角度來理解試試.

假設現在有乙個父類father,它裡面的變數需要占用1m記憶體.有乙個它的子類son,它裡面的變數需要占用0.5m記憶體.

現在通過**來看看記憶體的分配情況:

father f = new father();//系統將分配1m記憶體.

son s = new son();//系統將分配1.5m記憶體!因為子類中有乙個隱藏的引用super會指向父類例項,所以在例項化子類之前會先例項化乙個父類,也就是說會先執行父類的建構函式.由於s中包含了父類的例項,所以s可以呼叫父類的方法.

son s1 = s;//s1指向那1.5m的記憶體.

father f1 = (father)s; 相當於father f1 = new son(); 為向上型別轉換,可省略,因為子類就是父類,如貓就是動物

//這時f1會指向那1.5m記憶體中的1m記憶體,即是說,f1只是指向了s中例項的父類例項物件,所以f1只能呼叫父類的方法(儲存在1m記憶體中),而不能呼叫子類的方法(儲存在0.5m記憶體中).

son s2 = (son)f;  //error 不可直接向下型別轉換

//這句**執行時會報classcastexception.因為f中只有1m記憶體,而子類的引用都必須要有1.5m的記憶體,所以無法轉換.

son s3 = (son)f1; 強制型別轉換,為向下型別轉換,前提是父類引用要先指向子類物件

//這句可以通過執行,這時s3指向那1.5m的記憶體.由於f1是由s轉換過來的,所以它是有1.5m的記憶體的,只是它指向的只有1m記憶體.

示例:1 .如果你想實現多型,那麼必須有三個條件,父類引用,子類物件,方法覆蓋你這裡如果fathor類有乙個show()方法,那麼形成方法覆蓋,那麼此時就可以這麼寫:obj.show(),此刻形成了多型. 

2. 沒有方法覆蓋,那你這裡只能解釋為父類引用去訪問乙個子類的方法,當然,父類引用沒有這麼大範圍的許可權,當然會報錯 ps:多型實際上是一種機制,在編譯時刻,會生成一張虛擬表,來記錄所有覆蓋的方法,沒有被覆蓋的方法是不會記錄到這張表的.若乙個父類引用呼叫了沒有覆蓋的子類方法,那麼是不符合該錶的,那麼編譯時刻就會報錯. 在執行程式的時候,虛擬機會去這張虛擬表中找覆蓋的方法,比如引用中實際上存的是乙個子類物件引用,那麼就會去找子類中的相應的覆蓋的方法來執行

class

father

;

}

class

sonextends

father

void

show

()

}

class

demo

}

定義乙個父類型別的引用指向乙個子類的物件既可以使用子類強大的功能,又可以抽取父類的共性。

所以,父類型別的引用可以呼叫父類中定義的所有屬性和方法,而對於子類中定義而父類中沒有的方法,它是無可奈何的;

同時,父類中的乙個方法只有在在父類中定義而在子類中沒有重寫的情況下,才可以被父類型別的引用呼叫;

看下面這段程式:

上面的程式是個很典型的多型的例子。子類child繼承了父類father,並過載了父類的func1()方法,重寫了父類的func2()方法。過載後的func1(int i)和func1()不再是同乙個方法,由於父類中沒有func1(int i),那麼,父類型別的引用child就不能呼叫func1(int i)方法。而子類重寫了func2()方法,那麼父類型別的引用child在呼叫該方法時將會呼叫子類中重寫的func2()。

那麼該程式將會列印出什麼樣的結果呢?

很顯然,應該是「ccc」。

class

father

//這是父類中的func2()方法,因為下面的子類中重寫了該方法

//所以在父類型別的引用中呼叫時,這個方法將不再有效

//取而代之的是將呼叫子類中重寫的func2()方法

public

void

func2

()

}class

child

extends

father

//func2()重寫了父類father中的func2()方法

//如果父類型別的引用中呼叫了func2()方法,那麼必然是子類中重寫的這個方法

public

void

func2

()

}public

class

polymorphismtest

}

變數是不存在重寫覆蓋的!

public

class

a

public

class

bextends

a

測試類裡呼叫了這個方法

void

compare

()

控制台出來的是overrided

類中的屬性是沒有多型性的,即你在引用上面使用屬性時,系統只會去找引用的靜態型別中的那個屬性,而與它的實際型別無關。

靜態方法也是沒有多型性的。

父類引用指向子類物件

要理解多型性,首先要知道什麼是 向上轉型 我定義了乙個子類cat,它繼承了animal類,那麼後者就是前者是父類。我可以通過 cat c new cat 例項化乙個cat的物件,這個不難理解。但當我這樣定義時 animal a new cat 這代表什麼意思呢?很簡單,它表示我定義了乙個animal...

父類引用指向子類物件

是多型的一種實現方式 這樣做使程式靈活性更好,若有多個子類,只需改變引用就能實現不同的功能,而不需要改變程式 父類 a 子類 a1,a2 a obj1 new a1 a obj2 new a2 如果a有乙個方法是show 子類實現了show 那麼obj1.show 就是第乙個子類的show obj2...

父類引用指向子類物件

package fuleiyinyongzhixiang public class animal public void sleep package fuleiyinyongzhixiang public class person extends animal public void play pa...