關於多型的乙個經典例項

2021-10-01 06:16:25 字數 2304 閱讀 5557

廢話不多說,直接上**。。。

public class a

public string show(a obj)  

}public class b extends a

public string show(a obj) 

}public class c extends b

public class d extends b

public class test

}執行結果:

1--a and a

2--a and a

3--a and d

4--b and a

5--b and a

6--a and d

7--b and b

8--b and b

9--a and d

在這裡看結果1、2、3還好理解,從4開始就開始糊塗了,對於4來說為什麼輸出不是「b and b」呢?

首先我們先看一句話:當超類物件引用變數引用子類物件時,被引用物件的型別而不是引用變數的型別決定了呼叫誰的成員方法,但是這個被呼叫的方法必須是在超類中定義過的,也就是說被子類覆蓋的方法。這句話對多型進行了乙個概括。其實在繼承鏈中物件方法的呼叫存在乙個優先順序:this.show(o)、super.show(o)、this.show((super)o)、super.show((super)o)。

分析:我們先分析⑤,a2.show(c),a2是a型別的引用變數,所以this就代表了a,a2.show(c),它在a類中找發現沒有找到,於是到a的超類中找(super),由於a沒有超類(object除外),所以跳到第**,也就是this.show((super)o),c的超類有b、a,所以(super)o即(super)c為b、a,並且優先找c的上一級父類b(可以理解為就近原則),即在a中找show(b obj),但很遺憾沒找到,進而在a中找到了show(a obj),同時由於a2是b類的乙個引用且b類重寫了show(a obj),因此最終會呼叫子類b類的show(a obj)方法,結果也就是b and a。

再看④,這裡a2是引用變數,為a型別,它引用的是b物件,因此按照上面那句話的意思是說有b來決定呼叫誰的方法,所以a2.show(b)應該要呼叫b中的show(b obj),產生的結果應該是「b and b」,但是為什麼會與前面的執行結果產生差異呢?這裡我們忽略了後面那句話「但是這兒被呼叫的方法必須是在超類中定義過的」,那麼show(b obj)在a類中存在嗎?根本就不存在!所以這句話在這裡不適用?那麼難道是這句話錯誤了?非也!其實這句話還隱含這這句話:它仍然要按照繼承鏈中呼叫方法的優先順序來確認。所以它才會在a類中找到show(a obj),同時由於b重寫了該方法所以才會呼叫b類中的方法,否則就會呼叫a類中的方法。

再比如⑧,b.show(c),b是乙個引用變數,型別為b,則this為b,c是c的乙個例項,於是它到類b找show(c obj)方法,沒有找到,轉而到b的超類a裡面找,a裡面也沒有,因此也轉到第三優先順序this.show((super)o),this為b,o為c,(super)o即(super)c即b,因此它到b裡面找show(b obj)方法,找到了,由於b引用的是類b的乙個物件,因此直接鎖定到類b的show(b obj),輸出為"b and b」。

————————————————

按照同樣的方法我也可以確認其他的答案。

方法已經找到了但是我們這裡還是存在一點疑問,我們還是來看這句話:當超類物件引用變數引用子類物件時,被引用物件的型別而不是引用變數的型別決定了呼叫誰的成員方法,但是這個被呼叫的方法必須是在超類中定義過的,也就是說被子類覆蓋的方法。這我們用乙個例子來說明這句話所代表的含義:a2.show(b);

這裡a2是引用變數,為a型別,它引用的是b物件,因此按照上面那句話的意思是說有b來決定呼叫誰的方法,所以a2.show(b)應該要呼叫b中的show(b obj),產生的結果應該是「b and b」,但是為什麼會與前面的執行結果產生差異呢?這裡我們忽略了後面那句話「但是這兒被呼叫的方法必須是在超類中定義過的」,那麼show(b obj)在a類中存在嗎?根本就不存在!所以這句話在這裡不適用?那麼難道是這句話錯誤了?非也!其實這句話還隱含這這句話:它仍然要按照繼承鏈中呼叫方法的優先順序來確認。所以它才會在a類中找到show(a obj),同時由於b重寫了該方法所以才會呼叫b類中的方法,否則就會呼叫a類中的方法。

所以多型機制遵循的原則概括為:當超類物件引用變數引用子類物件時,被引用物件的型別而不是引用變數的型別決定了呼叫誰的成員方法,但是這個被呼叫的方法必須是在超類中定義過的,也就是說被子類覆蓋的方法,但是它仍然要根據繼承鏈中方法呼叫的優先順序來確認方法,該優先順序為:this.show(o)、super.show(o)、this.show((super)o)、super.show((super)o)。

繼承與多型的乙個簡單例項

程式結構 父為person類,person類個子類student和employee,employee類又有兩個子類,staff和faculty。繼承即子類可以繼承父類的資料域和方法 student類和employee類繼承了person類的資料域name,address phonenumber e ...

C 關於引用值的乙個例項

如下 所示 string item1 new string 1 string item2 new string 10 item2 0 china item2 1 china1 item2 2 china2 item1 item2 因為是引用型別,這裡的itme1會變成10個 int int1 new...

乙個經典錯誤

今天,在學習qt tutorial 8的時候,犯了乙個經典錯誤,在建構函式裡面覆蓋了 應該是這樣稱呼這種行為的吧 私有成員變數,導致私有成員變數沒有初始化,引起懸空指標,導致程式崩潰。出錯 如下 lcdrange.h ifndef lcdrange h define lcdrange h inclu...