不要new你的函數

來源:互聯網
上載者:User

<p$1$2$3$4$5$6> 

c#有個new函數的文法,但是我覺得這個東西用途很少。很多時候容易出現設計上的錯誤。

<p$1$2$3$4$5$6> 

基類有個虛A()函數,子類不想覆蓋,但是又想要這個名字,怎麼辦,那就是new A(){...}。

然後調用的時候,要想調用基類的,就用((基類)子類).A();要想用子類的,就子類.A();

<p$1$2$3$4$5$6> 

為什麼說這個比較容易出現設計上的問題。

1.類繼承系統的“介面”只能擴大,不能縮小

比如,你基類有個A函數,有個B函數,子類可以增加個C函數,但是不應該只是提供A函數,而沒有B函數。這個不單是從文法上,還要從語義上能說得過去,這種通過多態調用和直接調用出現語義上差別的做法,必然隱藏很多出錯的因素在裡面。就好象成龍說的:你們看到是這樣,用了也應該是這樣的。

2.縮小都原因都是因為子類不是基類

我們知道設計繼承關係有個很直觀的法則:子類是基類。比如秋刀魚是魚。在設計過程中,如果出現要縮小,只能說一開始這個抽象依據就是錯誤的,比如鯨魚不是魚(如果魚定義了鯨魚所沒有的介面)。

既然放棄了這個法則,那就屬於濫用文法的範疇,而不屬於物件導向的範疇。嚴格來說,就是簡陋笨拙的複製粘貼行為。不是說不能用,只是沒有設計上的優勢罷了。

<p$1$2$3$4$5$6> 

如果非要用,怎麼從設計上理解?

我的理解,這種在設計上的意義就是所謂的“實現繼承”。也就是子類只是為了利用基類的實現為目的。但是這種方式,也許對於c#來說,用組合比用繼承要好得多,為什嗎?因為c++ 有private繼承,但是c#沒有。

c++的私人繼承,子類不能通過基類來調用,這樣就根絕了多態調用的念頭。

<p$1$2$3$4$5$6> 

----------------------------------------------------

想不到大家討論的那麼積極,下面對討論做一些摘要(更新到80樓):

Zhenway:可以用new來改寫同名返回函數的類型,比如把傳回型別由基類改為子類類型,這在很多情境是有用的。

卡通一下:new未必和函數有關,也可以用在欄位上,所以並不是只是針對多態的情境。(而原文只是討論了多態的情境)

林靜止水

我通常在以下情況下使用new
1.不能對虛方法是用new
2.對屬性可使用new,並且是組合關係
3.比如某類a的屬性是類b,類c繼承類a,屬性需要繼承類b,新屬性可以用new
新屬性只完成強制轉換

淩晨的太陽

記得VS的提示是這樣的,當你企圖用override來重寫一個函數,或者直接編寫一個函數的時候,如果該函數在基類中已被定義,並且沒有virtual的時候,會提示使用new關鍵字。屬性也可以使用new,情況差不多。
顯然,new的使用和LZ的情境完全不同,概念也完全不同。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.