眾所周知绍昂,在C++羔飞,C# 等面向?qū)ο箝_發(fā)語言中,虛方法(函數(shù))是實(shí)現(xiàn)“多態(tài)”的基礎(chǔ)挎袜,其實(shí)現(xiàn)原理:運(yùn)行系統(tǒng)將根據(jù)對(duì)象的類型顽聂,自動(dòng)選擇適當(dāng)?shù)木唧w實(shí)現(xiàn)運(yùn)行,沒有定位虛方法的方法將不具備此特性盯仪。而要聲明虛方法紊搪,就不得不依賴關(guān)鍵字"virtual"。
在C++全景,C#等面向?qū)ο箝_發(fā)語言中耀石,虛方法是支持繼承的,且在使用的時(shí)候爸黄,還要注意以下幾點(diǎn):
一旦在基類里把某個(gè)方法聲明為虛方法滞伟,在子類里就不可能再把它聲明為一個(gè)非虛方法了。
如果拿不準(zhǔn)要不要把某個(gè)方法聲明為虛方法炕贵,那么最好把他聲明為虛方法梆奈。
在基類里把所有的方法都聲明為虛方法會(huì)讓最終生成的可執(zhí)行代碼的速度變得稍微慢一些,但是好處是可以一勞永逸的確保程序的行為符合預(yù)期称开。
在實(shí)現(xiàn)一個(gè)多層次的繼承關(guān)系時(shí)亩钟,頂級(jí)的基類應(yīng)該只有虛方法。
析構(gòu)器都是虛方法鳖轰,從編譯的角度看清酥,他們只是普通的方法。如果他們不是虛方法蕴侣,編譯器就會(huì)根據(jù)他們?cè)诰幾g時(shí)的類型而調(diào)用哪個(gè)在基類里定義的版本(構(gòu)造器)焰轻,那樣的話,有可能導(dǎo)致內(nèi)存泄露昆雀。
在C++中鹦马,只要在普通方法之前加上virtual關(guān)鍵字胧谈,就可以表示虛方法。
但在oc中荸频,很難找到virtual關(guān)鍵字或其等價(jià)的,其實(shí)oc中不但有虛方法客冈,甚至所有的方法都是虛方法旭从。
在oc中,覆蓋積累的方法只需要重寫即可场仲。無需加任何關(guān)鍵字和悦。但是在覆蓋其他基類的方法時(shí),必須決定是否要替換基類的方法的行為渠缕,或者擴(kuò)展或者補(bǔ)充該行為鸽素。如果想要替換基類的行為,提供自己的方法實(shí)現(xiàn)即可亦鳞;如果想要擴(kuò)展該基類的行為馍忽,調(diào)用基類實(shí)現(xiàn),并提供自己的代碼即可燕差。
通過發(fā)送消息(與調(diào)用方法的消息相同)到super來調(diào)用基類實(shí)現(xiàn)遭笋。通過將消息發(fā)送給super,就將該方法的基類代碼插入到重新實(shí)現(xiàn)的調(diào)用點(diǎn)徒探。
如果打算補(bǔ)充基類的實(shí)現(xiàn)行為瓦呼,應(yīng)該調(diào)用super。
如果打算替換基類的實(shí)現(xiàn)行為测暗,就不用調(diào)用super央串。
在oc中,實(shí)現(xiàn)這種"純虛方法"的類似功能碗啄,可以采用正式協(xié)議來實(shí)現(xiàn)质和,正式協(xié)議的方法,所有實(shí)現(xiàn)這個(gè)協(xié)議的類都必須實(shí)現(xiàn)挫掏。這就是一種驗(yàn)證侦另,也就是說,只要這個(gè)類可以實(shí)現(xiàn)這個(gè)協(xié)議尉共,那么他肯定可以處理協(xié)議中規(guī)定的方法褒傅,一個(gè)類可以實(shí)現(xiàn)任意多個(gè)協(xié)議。
要點(diǎn)###
(1)在Objective_C中袄友,所有的方法都是虛方法殿托。
(2)實(shí)現(xiàn)純虛方法,依靠正式協(xié)議來實(shí)現(xiàn)剧蚣。
(3)協(xié)議并不是真正的類支竹,它只能聲明方法旋廷,不能添加數(shù)據(jù)。
(4)非正式協(xié)議并不是真正的協(xié)議礼搁,它對(duì)代碼沒有約束力饶碘。