核心語法差異
| 關鍵字 | 用途 | 目標 | 關係 | 數量限制 | Java 版本演進 |
extends | 類繼承類 | 類 | is-a (泛化) | 單繼承 (一個父類) | 1.0+ |
extends | 介面繼承介面 | 介面 | 介面擴展 | 多繼承 (多個父介面) | 1.0+ |
implements | 類實現介面 | 介面 | 契約履行 | 多實現 (多個介面) | 1.0+ |
語法組合範例
// 1. 類繼承類 + 實現多介面
class Child extends Parent implements Serializable, Cloneable, Comparable { }
// 2. 介面繼承多介面
interface RichInterface extends Serializable, Cloneable, AutoCloseable { }
// 3. 抽象類實現介面 (可不實現所有方法)
abstract class AbstractRepo implements Repository { }
// 4. 類繼承類並實現介面 (順序固定:extends 在前)
class ServiceImpl extends BaseService implements Service, HealthCheck { }
繼承 vs 實現:語義與設計意圖
extends (繼承) - 「是一種」關係
- 代碼復用:獲得父類非私有欄位/方法
- 多態基礎:子類物件可當父類使用
- 強耦合:子類依賴父類實現細節,破壞封裝
- 單繼承限制:避免菱形繼承問題
- 適用場景:明確的層次結構、共享核心邏輯、模板方法模式
implements (實現) - 「能做某事」契約
- 定義規範:只宣告「做什麼」,不涉及「怎麼做」
- 鬆耦合:實現類可自由變更,調用者依賴介面
- 多實現:一個類可實現多個介面,組合能力
- 適用場景:插件架構、策略模式、回調、SPI、跨層解耦
Java 8+ 介面演進:模糊邊界
| 特性 | Java 7 介面 | Java 8+ 介面 | 影響 |
| 方法體 | 無 (隱式 abstract) | default / static 方法可有實現 | 介面可提供預設行為,減少抽象類需求 |
| 靜態方法 | 無 | 支援 | 工具方法可放介面,如 Stream.of() |
| 私有方法 | 無 | Java 9+ 支援 private 方法 | default 方法間可共享邏輯 |
| 構造子 | 無 | 無 | 介面仍無法有狀態初始化 |
| 實例欄位 | 無 (只有常量) | 無 | 無狀態,線程安全 |
default 方法與菱形問題解決
interface A { default void foo() { System.out.println("A"); } }
interface B { default void foo() { System.out.println("B"); } }
// 編譯錯誤:繼承了衝突的 default 方法
// class C implements A, B { }
// 必須顯式重寫解決衝突
class C implements A, B {
@Override public void foo() {
// 可選擇調用特定介面實現
A.super.foo(); // 輸出 A
// B.super.foo(); // 輸出 B
}
}
抽象類 vs 介面:選型決策樹
需要定義類型契約?
├── 是 → 介面
│ └── 需要共享代碼/狀態?
│ ├── 是 → 考慮 default 方法 (無狀態) 或 抽象類 (有狀態)
│ └── 否 → 介面
└── 否 → 具體類
需要多重實現組合能力?
├── 是 → 介面 (可多實現)
└── 否 → 視情況
需要構造子/實例初始化邏輯?
├── 是 → 抽象類/具體類
└── 否 → 介面
需要非 public 方法?
├── 是 → 抽象類 (protected/package-private)
└── 否 → 介面 (所有方法隱式 public)
經典設計模式中的角色
| 模式 | extends 角色 | implements 角色 |
| Template Method | 抽象父類定義骨架 | 子類實現具體步驟 |
| Strategy | -- | 策略介面 + 多實現 |
| Factory Method | 抽象工廠類 | 產品介面 |
| Adapter | 繼承被適配類 (類適配器) | 實現目標介面 |
| Decorator | 繼承抽象裝飾類 | 實現組件介面 |
實戰最佳實踐
- 優先使用介面:定義服務契約、API 邊界、插件點
- 抽象類作為骨架:共享欄位、構造子邏輯、模板方法、預設實現
- 組合優於繼承:
class Service implements Interface { private Helper helper; } 而非 class Service extends Helper
- 介面隔離原則:細粒度介面 (
Serializable、Cloneable、AutoCloseable) 而非大而全介面
- 避免深層繼承鏈:超過 3 層極難維護,扁平化設計
- 文檔契約:介面方法必須有 Javadoc 說明前置條件、後置條件、副作用
遷移指南:舊代碼現代化
// Before: 抽象類作為工具類集合
abstract class StringUtils {
static String join(String... parts) { ... }
static boolean isBlank(String s) { ... }
}
// After: 介面 + default 方法 (或直接用工具類)
interface StringUtils {
static String join(String... parts) { ... } // Java 8 static 方法
static boolean isBlank(String s) { ... }
// default 方法供實現類覆寫/擴展
default String customJoin(List parts) { return join(parts.toArray(new String[0])); }
}