抽象類別與介面是面向抽象程式設計的兩大基石,雖同樣無法直接實例化、皆支援多型,但設計意圖與適用場景截然不同。本文整理經典觀點、MSDN 建議與實戰經驗,建立決策框架。
| 維度 | 介面 | 抽象類別 |
|---|---|---|
| 繼承性 | 支援多重實作 | 單一繼承 |
| 成員類型 | 僅簽名(方法/屬性/事件/索引子) | 可含欄位、屬性、已實作方法、建構式 |
| 語意關係 | CAN-DO(行為契約) | IS-A(核心身分) |
| 適用對象 | 無關類別間的共通行為 | 關係緊密的類別階層 |
| 版本演進 | 不可變更,需新增介面 | 可新增預設實作,相容現有衍生類 |
| 值類型支援 | Struct 可實作 | 僅限參考類型 |
| 回呼支援 | 天然支援 | 不支援(單一繼承限制) |
dunai:抽象類別是具體類別的「最大公約數」;介面是將不相關類別「雜湊」成群體的契約。
shenfx:差異大的物件尋求共性 → 介面;共性大的物件尋求差異 → 抽象類別。
Dflying Chen:介面定義「溝通契約」;抽象類別封裝「共用行為」。
一醉解千愁:介面 = 粗略規範;抽象類別 = 規範+說明;類別 = 具體實作。
IDisposable、IComparable)I 前綴(如 IRepository)publicIRepositoryV2),勿修改既有介面Animal → Dog/Cat)protected 建構式、共用欄位、虛擬/抽象方法sealed、不可 new 實例static 或 virtual| 場景 | 推薦 | 理由 |
|---|---|---|
| 元件庫公開 API,長期維護多版本 | 抽象類別 | 基類新增虛擬方法不破壞衍生類 |
| Plugin 架構、第三方擴充點 | 介面 | 實作者零耦合,僅遵守契約 |
| 領域核心實體(訂單、商品、用戶) | 抽象類別 | 共享身分識別、狀態、預設行為 |
| 跨領域服務(日誌、快取、序列化) | 介面 | CAN-DO 行為,任意類別皆可實作 |
面對新類別設計時,依序自問:
「面向介面程式設計」不等於「盡量用介面」。抽象類別負責定義「是什麼」,介面負責定義「能做什麼」。架構師的智慧在於:在核心領域建立穩固的抽象類別階層,在系統邊界與橫切關注點以精簡介面定義契約,兩者互補,構建高內聚、低耦合、可演進的系統。
下一篇將以完整書店案例,示範兩者協作落地。