| 基底成員 | 衍生類別宣告 | 結果 | 編譯器訊息 |
|---|---|---|---|
virtual | override | **多型覆寫** (Polymorphic Override) | 無 |
virtual | new | **隱藏** (Non-polymorphic Hiding) | 警告 CS0108 (建議加 new) |
virtual | (無關鍵字) | **隱藏** (隱式 new) | 警告 CS0108 |
| 非 virtual | override | **編譯錯誤** | 錯誤 CS0506:無法覆寫非 virtual 成員 |
| 非 virtual | new | **隱藏** | 無 (明確意圖) |
| 非 virtual | (無關鍵字) | **隱藏** | 警告 CS0108 |
virtual:基底類別**允許**衍生類別覆寫。運行時依實際物件型別動態分派 (動態繫結)。override:衍生類別**實作**覆寫,**必須**配合基底 virtual/abstract/override。new:衍生類別**隱藏**基底同名成員,**靜態繫結** (依宣告型別呼叫)。不具多型性。sealed override:覆寫並**封鎖**進一步覆寫 (終極實作)。abstract:基底類別**強制**衍生類別實作 (隱含 virtual),基底不提供實作。using System;
public class Base
{
public virtual void VirtualMethod() => Console.WriteLine("Base.VirtualMethod");
public void NonVirtualMethod() => Console.WriteLine("Base.NonVirtualMethod");
}
public class Derived : Base
{
public override void VirtualMethod() => Console.WriteLine("Derived.VirtualMethod (Override)");
public new void NonVirtualMethod() => Console.WriteLine("Derived.NonVirtualMethod (New/Hide)");
}
public class Program
{
public static void Main()
{
Derived d = new Derived();
Base b = d; // 向上轉型
d.VirtualMethod(); // Derived.VirtualMethod (Override) ✅ 多型
b.VirtualMethod(); // Derived.VirtualMethod (Override) ✅ 多型
d.NonVirtualMethod(); // Derived.NonVirtualMethod (New) ✅ 靜態繫結看宣告型別
b.NonVirtualMethod(); // Base.NonVirtualMethod ✅ 靜態繫結看宣告型別
}
}
public class Animal
{
public virtual string Name { get; set; } = "Animal";
public virtual int Legs => 4; // 唯讀屬性
}
public class Dog : Animal
{
// 覆寫自動屬性:必須重寫 get/set 或僅 get
public override string Name
{
get => base.Name; // 或自訂邏輯
set => base.Name = value + " (Dog)";
}
// 覆寫唯讀屬性
public override int Legs => 4; // 同樣值,但展示語法
// 隱藏基底屬性 (非 virtual)
public new string Color { get; set; } = "Brown";
}
virtual 導致無法覆寫// 基底類別庫發布者
public class LibraryBase
{
public void DoWork() { } // ❌ 未標 virtual,第三方無法 override
}
// 第三方使用者
public class MyDerived : LibraryBase
{
// public override void DoWork() { } // 編譯錯誤 CS0506
public new void DoWork() { } // 只能隱藏,失去多型
}
**原則**:設計給繼承的類別,**預設將公共/受保護方法標為 virtual** (Java/C# 預設相反,C# 需顯式宣告)。
List list = new() { new Base(), new Derived() };
foreach (var item in list)
{
item.NonVirtualMethod(); // 全印 "Base.NonVirtualMethod" ❌ 非預期
}
new 濫用造成維護噩夢new 關鍵字消除警告,明確表達意圖。sealed overridepublic class Base { public virtual void Save() { } }
public class Middle : Base { public sealed override void Save() { } } // 封鎖
public class Leaf : Middle { /* public override void Save() { } */ } // 編譯錯誤
virtual,衍生加 override。virtual,衍生若需同名用 new (並註解原因)。sealed override。virtual,衍生**必須** override (抽象) 或可選 override (介面預設實作)。精準掌握 virtual/override/new/sealed 交互語意,是設計可擴充、行為可預測類別階層的基石。