重用的兩條路徑
- 繼承:編譯期靜態綁定,是「是一種」關係;
- 組合:執行期動態組合,是「有一個」關係。
組合的優勢
| 特性 | 繼承 | 組合 |
| 耦合度 | 高(破壞封裝,父類別變動影響子類別) | 低(只依賴介面) |
| 彈性 | 編譯期固定 | 執行期可動態替換成員物件 |
| 封裝性 | 差(protected 成員外洩) | 好(成員通常 private,客戶端不可見) |
| 複雜度 | 易濫用導致深層繼承樹 | 扁平、直觀 |
經典比喻:汽車「有一個」變速箱
class Car {
private Transmission transmission; // 組合
private Engine engine;
// 執行期可換裝不同變速箱
}
若用繼承:class Car extends Transmission —— 荒謬且僵化。
新手常見誤區
「繼承應無處不在」
導致:深層繼承樹、脆弱基底類別、難以測試。正確心法:
- 先嘗試組合(
private 成員物件);
- 若發現確實需要「是一種」關係與多型,再用繼承;
- 繼承應服務於介面契約,而非單純程式碼重用。
實務啟示
- 設計新類別時,預設用組合;
- 成員物件宣告
private,對外只暴露必要介面;
- 需要多型替換時,成員型別用介面宣告(
Transmission 而非 ManualTransmission)。
總結
組合提供更大的彈性、更好的封裝、更低的耦合。繼承是強力藥劑,用對地方是良藥,濫用則成毒藥。優先組合,謹慎繼承,是成熟物件導向設計師的標誌。
- 上一篇文章: Java 繼承機制:重用介面與 extends 關鍵字
- 下一篇文章: 實作隱藏與存取控制:Java 封裝機制全解析
Copyright ©
程式碼之家 All Rights Reserved