重寫 vs 多載:同名方法的兩種面貌
Override(重寫)
- 發生層級:父子類別之間(繼承關係)
- 前提條件:基類方法標記
virtual、abstract 或 override
- 簽名限制:參數、回傳型別、存取修飾詞必須完全一致
- 多態行為:執行時根據物件實際型別決定呼叫哪個版本
- 關鍵字:
override
Overload(多載)
- 發生層級:同一類別內部(或衍生類別隱藏基類成員)
- 區分依據:參數清單不同(型別、個數、順序),與回傳型別無關
- 解析時機:編譯期根據呼叫傳入的引數靜態綁定
- 關鍵字:無需特殊關鍵字
| 特性 | Override | Overload |
| 關係 | 垂直(繼承鏈) | 水平(同一作用域) |
| 多態 | 執行期動態分派 | 編譯期靜態綁定 |
| 回傳型別 | 必須相同 | 可不同 |
Abstract vs Virtual:可被覆寫的兩種契約
Abstract(抽象)
- 可修飾類別與成員
- 抽象類別不可實例化,強制衍生類實作
- 抽象成員不含實作本體,純粹定義契約
- 不可與
sealed、private 共存
Virtual(虛擬)
- 僅修飾成員(方法、屬性、索引子、事件)
- 提供預設實作,衍生類可選擇性覆寫
- 虛擬類別不存在(C# 無 virtual class)
選擇原則:預設實作有意義且常見 → virtual;必須由衍生類賦予具體行為 → abstract。
Class vs Struct:參考型別與實值型別的抉擇
| 特性 | Class(參考型別) | Struct(實值型別) |
| 記憶體配置 | 堆積,變數存參考 | 堆疊(或內嵌),變數存實值 |
| 指派語意 | 參考複製(雙方指向同一物件) | 實值複製(獨立副本) |
| 繼承 | 支援繼承、可為 abstract/sealed | 不可繼承、隱含 sealed |
| 預設值 | null | 所有欄位為 0/false/null |
| 適用場景 | 複雜物件、需共享狀態、多型行為 | 輕量資料結構、邏輯不可變、高頻配置 |
Const vs Readonly:不可變值的兩種定義時機
Const(編譯期常數)
- 值在編譯期確定,直接內嵌至呼叫端 IL
- 隱含
static,屬於類別而非實例
- 僅限基本型別、
string、null 參考
- 跨組件版本更新風險:呼叫端重新編譯前仍用舊值
Readonly(執行期常數)
- 值可在宣告時或建構函式中指定
- 屬於實例(非 static)或類別(static readonly)
- 支援任意型別(含陣列、自訂物件)
- 執行期讀取,跨組件更新安全
實務建議:公開常數且極少變更 → const;其餘情境優先 readonly。