3 回答

TA貢獻(xiàn)2041條經(jīng)驗(yàn) 獲得超4個(gè)贊
我很驚訝這里似乎達(dá)成了這樣的共識(shí),即默認(rèn)非虛擬化是正確的處理方式。我要講的是柵欄的另一面-我認(rèn)為是實(shí)用的。
大多數(shù)論據(jù)都像古老的“如果我們給你力量,你可能會(huì)傷害自己”這樣的論點(diǎn)讀給我聽。來自程序員嗎?
在我看來,像編碼員一樣,他不了解(或沒有足夠的時(shí)間)來設(shè)計(jì)自己的庫以進(jìn)行繼承和/或可擴(kuò)展性,是恰好產(chǎn)生了我可能需要修復(fù)或調(diào)整的庫的編碼員。覆蓋功能最有用的庫。
我不得不編寫丑陋,絕望的變通方法代碼(或放棄使用并推出自己的替代解決方案)的次數(shù),因?yàn)槲覠o法覆蓋太多,遠(yuǎn)遠(yuǎn)超過了我被咬過的次數(shù)(例如在Java中),通過覆蓋設(shè)計(jì)者可能沒有考慮過的地方。
默認(rèn)非虛擬使我的生活更加艱難。
更新: [正確地指出]我實(shí)際上沒有回答問題。所以-很抱歉遲到了....
我有點(diǎn)希望能夠?qū)懗鲆恍┫瘛?C#在默認(rèn)情況下將方法實(shí)現(xiàn)為非虛擬的方法,因?yàn)樽龀隽艘粋€(gè)錯(cuò)誤的決定,使程序?qū)Τ绦虻闹匾暢潭雀哂诔绦騿T”。(我認(rèn)為,根據(jù)該問題的其他一些答案(例如性能(過早的優(yōu)化,有人嗎?)或保證類的行為),這在某種程度上是合理的。)
但是,我意識(shí)到我只是在陳述自己的觀點(diǎn),而不是Stack Overflow想要的明確答案。當(dāng)然,我認(rèn)為,在最高層次上,確定的(但無濟(jì)于事的)答案是:
默認(rèn)情況下,它們是非虛擬的,因?yàn)檎Z言設(shè)計(jì)者需要做出決定,而這正是他們選擇的。
現(xiàn)在我想他們做出這個(gè)決定的確切原因我們將永遠(yuǎn)不會(huì)....哦,等等! 對(duì)話記錄!
因此,這里關(guān)于覆蓋API的危險(xiǎn)以及顯式設(shè)計(jì)繼承的需求的答案和評(píng)論似乎在正確的軌道上,但是都缺少一個(gè)重要的時(shí)間方面:Anders的主要關(guān)注點(diǎn)在于維護(hù)類或API的隱式跨版本合同。而且我認(rèn)為他實(shí)際上更關(guān)心的是允許.Net / C#平臺(tái)在代碼下進(jìn)行更改,而不是關(guān)注平臺(tái)頂部的用戶代碼更改。(他的“務(wù)實(shí)”觀點(diǎn)與我完全相反,因?yàn)樗菑牧硪粋?cè)看的。)
(但是他們不能只是默認(rèn)情況下選擇了虛函數(shù),然后在代碼庫中添加了“最終”字嗎?也許那是不完全一樣的。而且安德斯顯然比我聰明,所以我要撒謊。)

TA貢獻(xiàn)1863條經(jīng)驗(yàn) 獲得超2個(gè)贊
總結(jié)一下別人說的話,有以下幾個(gè)原因:
1-在C#中,語法和語義上有很多東西直接來自C ++。C ++默認(rèn)情況下不是虛擬的方法會(huì)影響C#。
2-默認(rèn)情況下,將每個(gè)方法虛擬化是性能問題,因?yàn)槊總€(gè)方法調(diào)用都必須使用對(duì)象的虛擬表。而且,這極大地限制了即時(shí)編譯器內(nèi)聯(lián)方法和執(zhí)行其他類型的優(yōu)化的能力。
3-最重要的是,如果默認(rèn)情況下方法不是虛擬的,則可以保證類的行為。當(dāng)它們默認(rèn)為虛擬時(shí)(例如在Java中),您甚至無法保證簡(jiǎn)單的getter方法會(huì)按預(yù)期進(jìn)行,因?yàn)樗赡軙?huì)被覆蓋以在派生類中做任何事情(當(dāng)然,您可以并且應(yīng)該使方法和/或最終課程)。
正如Zifre所提到的,您可能會(huì)想知道為什么C#語言沒有更進(jìn)一步,并且默認(rèn)情況下將類密封。這是關(guān)于實(shí)現(xiàn)繼承問題的整個(gè)辯論的一部分,這是一個(gè)非常有趣的話題。
添加回答
舉報(bào)