**實作繼承** 讓衍生類別繼承基類別的**欄位、屬性、方法實作**。衍生類別即擁有基類別的所有非私有成員,並可:
1. **繼承原樣使用** (不修改)。
2. **覆寫** — 以 virtual/override 替換實作。
3. **隱藏** — 以 new 定義同名成員 (非多型)。
4. **擴充** — 新增衍生類別專屬成員。
public class Animal {
public string Name { get; set; }
public int Age { get; set; }
// 虛擬方法:允許衍生類覆寫,提供預設實作
public virtual void MakeSound() {
Console.WriteLine($"{Name} makes a generic sound.");
}
// 虛擬屬性
public virtual string Habitat => "Unknown";
// 密封虛擬方法:允許覆寫一次,但禁止進一步覆寫
public virtual void Sleep() {
Console.WriteLine($"{Name} sleeps.");
}
// 非虛擬方法:不可覆寫,僅能隱藏
public void Breathe() {
Console.WriteLine($"{Name} breathes.");
}
// 密封類別:完全禁止繼承
// public sealed class SealedAnimal { ... }
}
public class Dog : Animal {
public string Breed { get; set; }
// 覆寫虛擬方法:多型生效
public override void MakeSound() {
Console.WriteLine($"{Name} barks: Woof!");
// base.MakeSound(); // 可選:呼叫基類實作
}
// 覆寫虛擬屬性
public override string Habitat => "Domestic / Worldwide";
// 覆寫密封虛擬方法 (若基類 Sleep 為 virtual 非 sealed)
// public sealed override void Sleep() { ... } // 密封此路徑
// 隱藏非虛擬成員:非多型,僅靜態繫結
public new void Breathe() {
Console.WriteLine($"{Name} breathes heavily (dog).");
}
// 衍生類專屬方法
public void Fetch() => Console.WriteLine($"{Name} fetches the ball!");
}
Animal a = new Dog { Name = "Buddy", Breed = "Golden Retriever" };
a.MakeSound(); // ✅ 輸出: "Buddy barks: Woof!" (虛擬調度)
a.Sleep(); // ✅ 輸出: "Buddy sleeps." (繼承基類實作)
a.Breathe(); // ⚠️ 輸出: "Buddy breathes." (靜態繫結至 Animal.Breathe)
Dog d = (Dog)a;
d.Breathe(); // ✅ 輸出: "Buddy breathes heavily (dog)." (靜態繫結至 Dog.Breathe)
d.Fetch(); // ✅ 衍生類專屬
| 關鍵字 | 位置 | 效果 |
|---|---|---|
virtual | 基類方法/屬性/索引子/事件 | 宣告可被覆寫,提供預設實作 |
override | 衍生類成員 | 替換虛擬成員實作,**多型調度** |
sealed | 類別 / override 方法 | 類別:禁止繼承;方法:禁止進一步覆寫 |
abstract | 類別 / 成員 | 類別:不可實例化;成員:無實作,**強制**衍生類覆寫 (隱含 virtual) |
new | 衍生類成員 | 隱藏基類同名成員,**無多型**,編譯器警告 CS0108 |
base | 衍生類內部 | 存取基類實作 (base.Method()、base.Property) |
Dog is an Animal ✅;Square is a Rectangle ❌ (寬高獨立性破壞)。class Dog { IAnimalBehavior Behavior; } 而非深層繼承樹。策略模式、裝飾模式替代繼承爆炸。
public abstract class DataProcessor {
// 模板方法:定義演算法骨架
public void Process() {
ReadData();
var data = TransformData(); // 抽象步驟
WriteData(data);
}
protected abstract string TransformData(); // 強制實作
protected virtual void ReadData() { Console.WriteLine("Reading..."); } // 可選覆寫
protected virtual void WriteData(string data) { Console.WriteLine($"Writing: {data}"); }
}
public class CsvProcessor : DataProcessor {
protected override string TransformData() => "CSV_DATA";
}
public class JsonProcessor : DataProcessor {
protected override string TransformData() => "JSON_DATA";
protected override void WriteData(string data) => Console.WriteLine($"JSON Output: {data}");
}
實作繼承是強大但危險的工具。**virtual/override** 啟用多型、**sealed** 限制擴充、**new** 僅為隱藏兼容、**abstract** 強制契約。遵循 LSP、優先組合、封裝易變點,將繼承深度控制在 2-3 層,才能發揮其代碼重用優勢而不陷入剛性、脆弱的類別階層。