<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 原則33:只有基類更新處理才使用 new 修飾符 **By D.S.Qiu** **尊重他人的勞動,支持原創,轉載請注明出處:[http://dsqiu.iteye.com](http://dsqiu.iteye.com)** 你可以使用 new 修飾符重定義從基類繼承的非虛成員。僅僅是因為你可以做某些事情卻不意味著你應該做。重定義非虛方法會有歧義的行為。大多數開發者看到下面兩塊代碼會立即認為他們執行的是同一件事情,如果它們繼承于同一個對象: 當涉及到 new 修飾符,就不是這樣的情況: ``` public class MyClass { public void MagicMethod() { // details elided. } } public class MyOtherClass : MyClass { // Redefine MagicMethod for this class. public new void MagicMethod() { // details elided } } ``` 這類實踐會困擾很多開發者。如果你對同一個對象調用同一個函數,你會期望相同的代碼被執行。實際上改變引用,即類名標簽,你調用函數改變了行為給人錯誤的感覺。這是不一致的。MyOtherClass 對象的行為取決于你怎么引用它。實際 new 修飾符的修飾不會使非虛方法變成虛方法。而是,它在不同類名作用域增加了不同的方法。 非虛方法是靜態綁定的。任何地方的引用 MyClass.MagicMethod() 的代碼調用都執行這個函數。運行時不會去查找子類定義的不同版本。虛函數,從另一方面講,是動態綁定的。運行時會根據對象的運行時類型調用真正的函數。 推薦避免使用 new 修飾符去重定義非虛函數并不是說建議你把基類的函數都定義為虛的。類庫設計者定義虛函數是有一定的講究。你定義虛函數說明任何子類期望改變虛函數的實現。虛函數集定義了子類期望改變的所有行為。“默認為虛”設計是說子類可以改變基類的所有行為。這確實是說你不會考慮子類修改的行為的所有后果。相反,你應該花時間去思考哪些方法和屬性聲明為多態。使那些并且只有那些是虛的。不要認為這可以限制你的類型的使用。而是,要把它作為提供自定義你的類型的行為的入口。 有一個地方,只有一地方,你要使用 new 修飾符。你在基類已經使用的方法簽名使用 new 修飾符就構成新的版本。你獲得的函數代碼取決于你類的函數名字。可能有其他程序集使用你的方法。你在你的類庫創建下面類,使用 BaseWidget 定義在其他類庫中: ``` public class MyWidget : BaseWidget { public void NormalizeValues() { // details elided. } } ``` 你完成你的組件,并且客戶正使用它。而后你發現 BaseWidget 公司發布了新版本。渴望得到新的特性,你理解購買她并嘗試構建 MyWidget 類。就會失敗因為 BaseWidget 自己添加了 NormalizeValues 方法: ``` public class BaseWidget { public void Normalizevalues() { // details elided. } } ``` 這就會有問題。你的基類偷偷在你的類名作用域下加了一個方法。有兩種方式修復它。你可以改變你的類型 NormalizeValues 方法的名字。注意直觀上認為 BaseWidget.NormalizeValues() 和 MyWidget.NormalizeValues() 在語意上的相同操作。如果不是,你不應該調用基類的實現。 ``` public class MyWidget : BaseWidget { public void NormalizeAllValues() { // details elided. // Call the base class only if (by luck) // the new method does the same operation. base.NormalizeValues(); } } ``` 或者,你可以使用 new 修飾符: ``` public class MyWidget : BaseWidget { public void new NormalizeValues() { // details elided. // Call the base class only if (by luck) // the new method does the same operation. base.NormalizeValues(); } } ``` 如果你可以得到 MyWidget 類的所有客戶端代碼,你可以改變方法名字因為這很容易長期運行。但如果你是向世界發布 MyWidget 類,就會強制你的所有使用者做無數的更改。這就是 new 修飾符派上用場的地方。你的客戶可以不更改繼續使用 NormalizeValues() 方法。沒有人會調用 BaseWidget.NormalizeValues() 因為它在之前不存在。 new 修飾符可以處理這樣的情況,即升級基類使得有一個成員和之前聲明的類有沖突的情況。 當然,隨著時間的推移,你的使用者可能需要使用 BaseWidget.NormalizeValues() 方法。那樣你還是回到原來的問題:兩個方法看起來相同但是表現卻不同。考慮所有 new 修飾符的長期后果。有時,短期更改你的方法是不方便卻更好。 new 修飾符必須謹慎使用。如果你不分青紅皂白,你就在創建歧義的方法。它只用于這個在升級基類引起和你的類沖突的特例。即使是那樣的情況,在使用它之前也要仔細考慮。最重要的是,不要在其他情況使用它。 小結: 盡量不用 new 修飾符,減少歧義方法。 歡迎各種不爽,各種噴,寫這個純屬個人愛好,秉持”分享“之德! 有關本書的其他章節翻譯請[點擊查看](/category/297763),轉載請注明出處,尊重原創! 如果您對D.S.Qiu有任何建議或意見可以在文章后面評論,或者發郵件(gd.s.qiu@gmail.com)交流,您的鼓勵和支持是我前進的動力,希望能有更多更好的分享。 轉載請在**文首**注明出處:[http://dsqiu.iteye.com/blog/2087773](/blog/2087773) 更多精彩請關注D.S.Qiu的博客和微博(ID:靜水逐風)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看