繼承、抽象類、接口構成 Java 物件導向設計的「鐵三角」。本文從語法規範、記憶體模型、設計原則、模式應用、演進特性 (Java 8/9/17+) 五個維度,系統構建完整知識體系。
extends,單繼承 (一個父類),多層繼承形成鏈public/protected 可見;private 不可見 (但透過 getter/setter 間接訪問);default 同包可見toString/equals/hashCode/clone/finalize/wait/notify/getClassclass Grandpa {
Grandpa() { System.out.println("Grandpa()"); }
}
class Father extends Grandpa {
Father() { System.out.println("Father()"); }
}
class Child extends Father {
Child() { System.out.println("Child()"); }
}
// new Child() 輸出:
// Grandpa()
// Father()
// Child()
// 規則:隱式/顯式 super() 必須為建構子第一句 → 父類優先初始化 → 保證父類狀態就緒
| 關係 | 定義 | 例子 |
|---|---|---|
| 擴充 | 子類新增父類無同名方法 | Father 無 fly(),Child 定義 fly() |
| 覆寫 | 同名、同參數、同返回類型 (或协变)、權限不降低、拋出異常不擴大 | @Override void show() |
| 重載 | 同名、參數列表不同 (類型/數量/順序) | void print(int) / void print(String) |
final class:不可繼承 (String、Integer、LocalDate)final method:不可覆寫 (getClass、wait、Thread.run)final field:引用不可變 (對象內部狀態仍可變),建構子初始化Fruit f = new Apple();
System.out.println("Fruit: " + f); // 隱式調用 f.toString()
// 等價於
System.out.println("Fruit: " + String.valueOf(f)); // null 安全
abstract class:不可實例化,可含抽象/非抽象方法、欄位、建構子、靜態方法、內部類abstract method:無方法體,子類必須實現 (除非子類也 abstract)public abstract class DataProcessor {
// final 鎖定演算法骨架
public final void process() {
readData();
validate();
transform();
writeResult();
}
protected abstract void readData();
protected abstract void transform();
protected abstract void writeResult();
// Hook 方法:預設空實現,子類可選擇性覆寫
protected void validate() { }
protected void beforeWrite() { }
}
public class CsvProcessor extends DataProcessor {
@Override protected void readData() { /* CSV 讀取 */ }
@Override protected void transform() { /* 轉換邏輯 */ }
@Override protected void writeResult() { /* 寫入 DB */ }
@Override protected void validate() { /* CSV 專屬校驗 */ }
}
| 版本 | 新特性 | 影響 |
|---|---|---|
| Java 7- | 常量、抽象方法 | 純契約,無實現 |
| Java 8 | default 方法、static 方法、函數式介面 (@FunctionalInterface) | 默認實現、靜態工具、Lambda 基礎 |
| Java 9 | private 方法、private static 方法 | default 方法間代碼復用、封裝 |
| Java 17+ | sealed 介面 (許可實現類) | 受控繼承、模式匹配穩盡性檢查 |
interface A { default void foo() { System.out.println("A"); } }
interface B { default void foo() { System.out.println("B"); } }
class C implements A, B {
// 必須顯式覆寫解決衝突
@Override public void foo() {
A.super.foo(); // 顯式選擇調用 A 的默認實現
// B.super.foo();
}
}
需要構建類別體系嗎? ├─ 是 → 需要共享狀態/代碼/建構子邏輯? → 抽象類 │ ├─ 否 → 定義能力契約、多實現、插件化、函數式? → 介面 │ └─ 兩者兼備 → 抽象類實現介面 (如 AbstractList implements List) └─ 否 → 工具類用 final class + static methods / 單例用 enum
@FunctionalInterface public interface Converter{ T convert(F from); // 只能有一個抽象方法,default/static/Object 方法不計數 } // 使用 Converter toInt = Integer::valueOf; // 方法引用 Converter toInt2 = s -> Integer.parseInt(s); // Lambda Integer result = toInt.convert("123");
// 繼承:強耦合、脆弱、單一維度
class Bird { void fly() {} }
class Penguin extends Bird { /* 不會飛 */ }
// 組合:靈活、多維度、運行期可變
interface FlyBehavior { void fly(); }
class FlyWithWings implements FlyBehavior { ... }
class FlyNoWay implements FlyBehavior { ... }
class Bird {
private FlyBehavior flyBehavior;
public void setFlyBehavior(FlyBehavior fb) { this.flyBehavior = fb; }
public void performFly() { flyBehavior.fly(); }
}
// 策略模式:運行期動態切換飛行行為
// 僅允許列出的類實現/繼承,編譯器強制檢查
public sealed interface Shape permits Circle, Rectangle, Triangle { }
public final class Circle implements Shape { ... }
public final class Rectangle implements Shape { ... }
public non-sealed class Triangle implements Shape { ... } // 可繼承
// 模式匹配 switch (JEP 441) 穩盡性檢查
public double area(Shape s) {
return switch (s) {
case Circle c -> Math.PI * c.radius() * c.radius();
case Rectangle r -> r.width() * r.height();
case Triangle t -> 0.5 * t.base() * t.height();
// 無 default,編譯器保證覆蓋所有許可實現
};
}
public record User(Long id, String name, String email) {
// 自動生成:final fields、canonical constructor、getter、equals/hashCode、toString
// 可添加驗證邏輯
public User {
if (name == null || name.isBlank()) throw new IllegalArgumentException("Name required");
email = email.toLowerCase(); // 正規化
}
}
繼承提供「is-a」強關聯與代碼復用,抽象類鎖定演算法骨架並共享狀態,接口定義「can-do」能力契約支援多實現。現代 Java 通過 default/private/sealed/record 等特性,極大豐富了介面表達力,模糊了抽象類與介面邊界。遵循 LSP/ISP/DIP、組合優於繼承、優先介面編程,善用 @Override/@FunctionalInterface/sealed 編譯器輔助,即可設計出高內聚、低耦合、可演進的領域模型。