中文字幕日韩一区二区_国产一区二区av_国产毛片av_久久久久国产一区_色婷婷电影_国产一区二区精品

虛方法的使用

《編程絮語(yǔ)》之一

virtual

C#的語(yǔ)法脫胎于C++,因而保留了virtual關(guān)鍵字,可以定義一個(gè)虛方法(或虛屬性)。一個(gè)類的成員被定義為virtual,就意味著它在告訴自己的子類:我準(zhǔn)備了一筆遺產(chǎn),你可以全盤(pán)接受,也可以完全拒絕或者修改我的遺囑。顯然,虛方法授予子類的權(quán)利甚至大于抽象方法。子類面對(duì)抽象方法只有重寫(xiě)(override)的權(quán)利,而對(duì)于虛方法,它還可以選擇完全繼承。

毫無(wú)疑問(wèn),虛方法破壞了對(duì)象的封裝性。如果不加約束的使用,會(huì)對(duì)調(diào)用方造成破壞,至少它有可能破壞子類與父類之間在外在行為上的一致性。因此,當(dāng)我們?cè)谥貙?xiě)虛方法時(shí),務(wù)必要遵循Liskov替換原則。我們要保證對(duì)于調(diào)用方而言,子類對(duì)于父類是完全可以替換的。這里所謂的“替換”,是指子類不能破壞調(diào)用方對(duì)父類行為的期待。準(zhǔn)確地說(shuō),子類在重寫(xiě)父類的虛方法時(shí),必須遵循調(diào)用該方法的前置條件與后置條件。這也是“契約式設(shè)計(jì)”的思想。最理想的狀態(tài)是讓使用對(duì)象甚至無(wú)法知道是否存在派生類[1]。即類的繼承體系對(duì)于調(diào)用者而言,必須體現(xiàn)外部接口的一致性,這樣才能做到調(diào)用者對(duì)派生類無(wú)知。

如果確實(shí)需要重寫(xiě)父類的方法,最好的方式是擴(kuò)展而不是修改。這實(shí)際上也是開(kāi)放-封閉原則的體現(xiàn)。例如在Decorator模式中,我們重寫(xiě)父類方法的目的,是為了實(shí)現(xiàn)對(duì)該方法的裝飾。Proxy模式的實(shí)現(xiàn)同樣如此。Michael C. Feathers對(duì)此給出的忠告是[2]:
1)盡可能避免重寫(xiě)具體方法。
2)倘若真的重寫(xiě)了某個(gè)具體方法,那么看看能否在重寫(xiě)方法中調(diào)用被重寫(xiě)的那個(gè)方法。

Feathers的忠告是針對(duì)Java語(yǔ)言,因?yàn)樵贑#中我們無(wú)法重寫(xiě)具體方法,只能利用new關(guān)鍵字在子類中新建一個(gè)相同方法簽名的具體方法,而這樣的方法并不具備多態(tài)性。這里涉及到一個(gè)有趣的話題,是關(guān)于Java和C#的比較。在Java語(yǔ)言中,如果沒(méi)有添加任何關(guān)鍵字,則方法默認(rèn)就是虛方法,任何子類都可以重寫(xiě)它。C#則相反,它對(duì)虛方法給予了顯式的定義。Java語(yǔ)言的締造者顯然是“性本善”論者,他認(rèn)為所有子類的實(shí)現(xiàn)者均抱著善意的態(tài)度來(lái)對(duì)待父類的方法,因而他賦予了子類相當(dāng)程度的自由,但卻可能被別有用心者偷偷打開(kāi)封裝的后門(mén)。如果確有非常重要的隱私防止被篡改,則可以利用final關(guān)鍵字來(lái)強(qiáng)制保護(hù)。C#語(yǔ)言的發(fā)明者則持有“性本惡”的論調(diào),他惡意地揣測(cè)子類總是會(huì)不懷好意,所以提供了一套默認(rèn)的強(qiáng)權(quán),來(lái)保護(hù)父類的隱私。如果需要對(duì)子類開(kāi)放,則明確地聲明為virtual,這就牢牢地把控制權(quán)攥緊在父類的手中。

C#保守的做法使得語(yǔ)言的特質(zhì)更加安全(當(dāng)然,Java會(huì)更加自由),我們可以使用virtual的自由性,搭配方法的訪問(wèn)限制,搭建一個(gè)安全合理的白盒框架。virtual關(guān)鍵字的含意本身就是面向子類的,所以,我們應(yīng)該盡可能地將其放在protected方法中使用。如果該方法代表的行為確實(shí)需要公開(kāi)給調(diào)用者,我們可以定義一個(gè)公開(kāi)的具體方法,在其中調(diào)用一個(gè)受保護(hù)的虛方法。

在Template Method模式中,體現(xiàn)了C#這種劃分具體方法和虛方法的好處。Template Method模式要求子類只能部分地替換父類的實(shí)現(xiàn),整個(gè)骨架則必須保持固定不變。在父類中,我們將模板方法定義為具體方法,將基本方法定義為抽象方法。模板方法規(guī)定了基本方法的調(diào)用順序,如果我們可以在子類中重寫(xiě)模板方法,就可能破壞基本方法的調(diào)用順序,從而對(duì)整個(gè)策略造成影響。Strategy模式就不存在這個(gè)問(wèn)題,因?yàn)樗牟呗允钦w的。Template Method模式在模板方法中規(guī)定的骨架,實(shí)際上就是為調(diào)用者制訂的前置條件和后置條件。

有一種說(shuō)法是不要在虛方法中訪問(wèn)私有字段[3]。這存在一定的合理性。因?yàn)橐坏┪覀冊(cè)诟割惖奶摲椒ㄖ性L問(wèn)了私有字段,那么在子類重寫(xiě)該虛方法時(shí),由于無(wú)法獲得父類的私有字段值,就可能會(huì)導(dǎo)致該字段值的缺失。但這種說(shuō)法并不完全準(zhǔn)確。一方面,我們認(rèn)為L(zhǎng)iskov替換原則主要是為了約束Is-A關(guān)系在行為上的一致性[4],如果該字段對(duì)行為不會(huì)造成影響,則無(wú)大礙。另一方面,這也說(shuō)明我們?cè)谥貙?xiě)虛方法時(shí),最佳實(shí)踐還是需要在重寫(xiě)的同時(shí),調(diào)用父類的虛方法,如Decorator模式的實(shí)現(xiàn)方式。

[1] Alan Shalloway, James R. Trott  Design Patterns Explained
[2] Michael C. Feathers  Working Effectively with Legacy Code
[3] Dino Esposito, Andrea Saltarello  Microsoft.NET Architecting Applications for the Enterprise
[4] Robert C. Martin Agile Software Development:Principles,Patterns and Practices

NET技術(shù)虛方法的使用,轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: av性色全交蜜桃成熟时 | 中文字幕在线观看一区二区 | 亚洲精品欧美 | 男女视频在线免费观看 | 欧美国产一区二区 | 九九99靖品| 自拍偷拍av | 在线视频日韩 | 国产偷录视频叫床高潮对白 | 日韩字幕| 香蕉视频91 | 久久一区精品 | 一级黄色片网站 | 成人午夜在线 | 男人的天堂在线视频 | 色必久久 | 中国三级黄色录像 | 日韩视频在线免费观看 | www.亚洲.com | 99精品视频一区二区三区 | 日韩毛片在线观看 | 久久福利电影 | 久夜精品 | 精品乱码一区二区三四区 | 日本aⅴ中文字幕 | av网站免费观看 | 午夜激情视频在线 | 国产精品久久久久久久久污网站 | 激情五月综合网 | 久久精品视频在线观看 | 天堂在线网 | 最近日韩中文字幕 | av在线免费播放 | 国产一区999 | av免费网站在线观看 | 中文字幕在线第二页 | 午夜av免费 | 久草在线影 | 亚洲性视频网站 | 久在线 | 一区二区免费视频 |