首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 多型與 new 關鍵字深度剖析:虛擬方法、隱藏、介面重新實作

     編輯:關於C#

多型核心機制

基類以 virtual 宣告方法,衍生類以 override 重寫,透過基類參考指向衍生類物件時,CLR 依實際物件型別動態分派方法:

class Base { public virtual void Print() => Console.WriteLine("Base"); }
class Derived : Base { public override void Print() => Console.WriteLine("Derived"); }

Base b = new Derived();
b.Print(); // 輸出: Derived (動態繫結)

new 關鍵字:隱藏而非覆寫

new 宣告新成員隱藏基類同名成員,不參與虛擬分派:

class Base { public virtual void Print() => Console.WriteLine("Base"); }
class DerivedNew : Base { public new void Print() => Console.WriteLine("DerivedNew"); }

Base b = new DerivedNew();
b.Print(); // 輸出: Base (靜態繫結至 Base.Print)
DerivedNew d = new DerivedNew();
d.Print(); // 輸出: DerivedNew (靜態繫結至 DerivedNew.Print)

關鍵差異對照

特性overridenew
多型參與是否
基類需求virtual/abstract/override任意成員
基類呼叫base.Method()base.Method() (在衍生類內部)
解除隱藏不適用轉型為基類型別呼叫
編譯警告無隱藏基類成員會警告 (CS0108)

介面重新實作 介面重新實作:new 的進階用法

若衍生類同時實作介面,可用 new + 介面宣告「切斷」與基類虛擬方法的連結,並重新綁定至介面:

interface IFace { void Print(); }
class Base : IFace { public virtual void Print() => Console.WriteLine("Base"); }
class Derived : Base, IFace
{
    public new void Print() => Console.WriteLine("Derived via IFace");
}

IFace f = new Derived();
f.Print(); // 輸出: Derived via IFace (介面呼叫解析至 Derived.Print)
Base b = new Derived();
b.Print(); // 輸出: Base (基類呼叫解析至 Base.Print)

原理:new 切斷與 Base.Print 的虛擬槽位關聯;class Derived : IFace 讓編譯器將 Derived.Print 視為 IFace.Print 的隱式實作,佔用新的虛擬槽位。

設計抉擇:誰錯了?

  • 若基類 virtual 是合理的 (期望多型),衍生類用 new 破壞契約 → 衍生類設計錯誤,應改用 override 或更換方法名。
  • 若基類 virtual 不合理 (非所有衍生類皆適用),基類應改為 abstract 強制衍生類實作,或移除 virtual。
  • 實務建議:基類核心行為用 abstract,預設實作下移至具體衍生類,避免 new 產生困惑。

Stream 案例啟示

Stream.Seek 為 abstract,但 NetworkStream 不支援定位。設計採用 CanSeek 屬性讓呼叫端執行期檢查,而非編譯期強制。這比拋出 NotSupportedException 更優雅,也避免了「不支援的作業」違反里氏替換原則。

最佳實踐總結

  1. 預設使用 virtual/override 實現多型。
  2. 僅在必須隱藏基類非虛擬成員、或介面重新實作時使用 new。
  3. 使用 new 時務必加上 // 隱藏基類成員: 說明原因 註解。
  4. 考慮將基類方法設為 abstract 強制衍生類正確實作,杜絕 new 濫用。
  5. 介面重新實作是進階技巧,僅用於修正非預期多型行為的邊界情況。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved