本篇博客我們來(lái)學(xué)習面向對象的多態(tài)性,多態(tài)性主要的表現形式就是在繼承中當派生類(lèi)從基類(lèi)繼承時(shí),它會(huì )獲得基類(lèi)的所有方法、字段、屬性和事件。當父類(lèi)和子類(lèi)的成員簽名相同的時(shí)候,我們可以定義讓子類(lèi)的這個(gè)同名成員以何種形式顯示出來(lái),父類(lèi)的這個(gè)的成員在子類(lèi)中又用何種方式存在,這種多面的表現方法我們稱(chēng)為多態(tài)。如果我們要更改基類(lèi)的數據和功能時(shí),也就是說(shuō)子類(lèi)中可以以自己的方式去實(shí)現父類(lèi)的功能,有兩種方式:1.我們還在子類(lèi)中可以使用override關(guān)鍵字重寫(xiě)基類(lèi)中用virtual關(guān)鍵字修飾的虛擬的基成員;2.可以在子類(lèi)中使用new關(guān)鍵字讓派生成員替換基成員,此時(shí)基類(lèi)成員只是被有意的隱藏掉了。
舉一個(gè)現實(shí)生活的例子,我們來(lái)理解一下多態(tài),爸爸如果有一套房子留給了兒子,并對兒子說(shuō):這個(gè)房子我裝修了一下,如果你不喜歡這個(gè)風(fēng)格,可以自己再重新翻新一下,但是我就有一個(gè)要求,就是這個(gè)房子唯一不變就是我喜歡的掛在走廊墻上的一張油畫(huà),你不許拆掉它。兒子欣然同意,拿到鑰匙去看了看房子,兒子有點(diǎn)對爸爸的審美產(chǎn)生了質(zhì)疑,裝修的風(fēng)格也太古樸了,于是兒子決定把客廳和臥室全部裝修了,改成了后現代主義的風(fēng)格,這時(shí)發(fā)生了我們所說(shuō)的多態(tài)的第一種方式,被稱(chēng)為重寫(xiě)或覆寫(xiě),爸爸給房子時(shí),把允許重新裝修的地方用virtual關(guān)鍵字修飾,兒子就可以用override關(guān)鍵字修飾那些允許重新裝修的房間,這時(shí)父親來(lái)到這個(gè)房子時(shí)會(huì )發(fā)現房子的客廳和臥室全部改變了。裝修完客廳和臥室后,兒子怎么看都覺(jué)得走廊上的油畫(huà)太格格不入了,因為油畫(huà)的內容是田園風(fēng)情,這時(shí)兒子想起爸爸不讓動(dòng)這幅畫(huà),所以?xún)鹤酉氲搅艘粋€(gè)方法,就買(mǎi)了一副新的抽象派的油畫(huà)蓋在爸爸的畫(huà)上面,這樣爸爸如果來(lái)到家,想看自己的畫(huà),也是存在的,這時(shí)發(fā)生的就是第二種方式,如果爸爸想在兒子的房子里看自己的東西,就使用base關(guān)鍵字,兒子的新油畫(huà)用new關(guān)鍵字隱藏住爸爸的話(huà)。
通過(guò)這個(gè)例子我們應該就能理解一點(diǎn)多態(tài)的含義了,我們先來(lái)學(xué)習第一種情況:重寫(xiě)。在使用重寫(xiě)的時(shí)候,一定要注意到一點(diǎn),就是為了讓子類(lèi)可以完全的重寫(xiě)父類(lèi)中的成員,父類(lèi)在定義這些成員的時(shí)候,一定要使用virtual關(guān)鍵字,讓可以重寫(xiě)的方法成為虛方法,讓可以重寫(xiě)的屬性成為虛屬性,子類(lèi)在重寫(xiě)這個(gè)方法或屬性的時(shí)候,將virtual替換成override關(guān)鍵字,代表已將父類(lèi)的成員替換為了它自己的成員并實(shí)現。我們來(lái)看一下具體的語(yǔ)法,為了舉例方便,我采用的是方法重寫(xiě)的實(shí)例,如:
class FatherClass
{public virtual void Method(){}}
class SonClass:FatherClass
{public override void Method(){}}
大家來(lái)看看父類(lèi)中的方法,按照我們上節課所學(xué)的如果父類(lèi)中的成員不是private修飾時(shí),子類(lèi)中是都可以訪(fǎng)問(wèn)到一個(gè)成員,但是重寫(xiě)是特殊的,根據我舉的例子大家回憶一下,這時(shí)如果父親來(lái)到兒子的房子,將會(huì )只存在被兒子重新裝修的客廳和臥室,這兩個(gè)屋原來(lái)的風(fēng)格都不存在了。也就是說(shuō),在子類(lèi)中,這兩個(gè)屋子只有一種形態(tài),就是兒子重新裝修定義的。雖然其他的屋子父親也允許兒子裝修,使用了virtual關(guān)鍵字修飾了,但是因為兒子沒(méi)有使用override關(guān)鍵字重新裝修,其他幾個(gè)屋的表現形態(tài)還是父親原先存在的。這就說(shuō)明了一點(diǎn),子類(lèi)要想重寫(xiě)父類(lèi)的方法,必須是父類(lèi)定義了virtual,子類(lèi)使用override。當如果我想在子類(lèi)的方法中再用父類(lèi)的那個(gè)被覆蓋的方法時(shí),只需要使用base關(guān)鍵字就可以代表繼承的父類(lèi)了,base關(guān)鍵字我們在上節課的類(lèi)七構造方法的繼承中也學(xué)到過(guò)。我們把上面的語(yǔ)法在子類(lèi)的Method方法中,加base用法,基本語(yǔ)法如下:
public override void Method()
{
base.Method();
}
這樣的話(huà),在調用子類(lèi)的Method方法時(shí),雖然重寫(xiě)了這個(gè)方法,但是使用base關(guān)鍵字又再次引用了父類(lèi)的Method方法。
當父類(lèi)定義了virtual,而子類(lèi)的同名方法沒(méi)有使用override重寫(xiě),這樣是可以的,這時(shí)子類(lèi)中仍然包括父類(lèi)的方法,也就是說(shuō)子類(lèi)中有兩個(gè)同名的方法,但是編譯器在我們創(chuàng )建子類(lèi)對象的時(shí)候,會(huì )顯示子類(lèi)的方法,而不會(huì )顯示繼承自父類(lèi)那個(gè)同名的方法。如果你使用VS編譯這樣情況時(shí),它會(huì )有一個(gè)警告:子類(lèi)的方法將隱藏父類(lèi)的方法。如果想重寫(xiě)請在子類(lèi)中加入override關(guān)鍵字,如果想隱藏請使用new關(guān)鍵字。使用override關(guān)鍵字剛才我們已經(jīng)講過(guò)了,如果用new就代表創(chuàng )建一個(gè)新的方法,這個(gè)子類(lèi)中的新方法隱藏父類(lèi)的方法,這就是我們說(shuō)的第二種多態(tài)的形式隱藏父類(lèi)的方法。
隱藏父類(lèi)方法,父類(lèi)可以是virtual修飾的虛方法,也可以是普通方法應該在子類(lèi)中顯式的使用new關(guān)鍵字,告知編譯器當調用子類(lèi)的這個(gè)方法時(shí),請顯示出子類(lèi)自定義的功能,當然如果要顯示父類(lèi)的方法也同樣可以使用base關(guān)鍵字,我們來(lái)看下面的語(yǔ)法:
class FatherClass
{public void Method(){}}
class SonClass:FatherClass
{public new void Method()
{
base.Method();
}
}
我今天所舉出的實(shí)例比較簡(jiǎn)單,就是定義了3個(gè)類(lèi)一個(gè)包含入口函數的Program類(lèi)、一個(gè)F類(lèi),一個(gè)S類(lèi)繼承了F類(lèi),在F和S中各定義了3個(gè)方法,對照結果我們來(lái)看一下:




























































































































在Method2方法中我寫(xiě)base.Method1(),就想告訴大家,base關(guān)鍵字可以調用出父類(lèi)所能繼承到子類(lèi)的任何一個(gè)成員,同學(xué)們課下也可以試一試下面兩種情況:一,如果父類(lèi)使用virtual,子類(lèi)使用new,建立第4種Method4方法,也同樣執行這三種對象調用Method4,結果應該和Method方法一致的。還是印證了我說(shuō)過(guò)的當子類(lèi)中用new時(shí),無(wú)論父類(lèi)是虛方法還是普通方法,都會(huì )隱藏父類(lèi)方法。二,如果同學(xué)在子類(lèi)中只出現override關(guān)鍵字,而父類(lèi)中沒(méi)有virtual相呼應,編譯器是會(huì )報錯的。
相信通過(guò)這個(gè)實(shí)例大家應該會(huì )應用這四個(gè)關(guān)鍵字了,可以有的同學(xué)還是不明白父類(lèi)用子類(lèi)來(lái)實(shí)現的方式,沒(méi)關(guān)系!用我說(shuō)的爸爸到兒子家的例子仔細想想就能明白了,這種用法最常見(jiàn)的形式就是當抽象類(lèi)和接口要實(shí)例成對象的時(shí)候,都是采用子類(lèi)來(lái)實(shí)現的,我們下節課會(huì )講到。
聯(lián)系客服