Java 8 前,接口只能聲明抽象方法。一旦發布,無法在不破壞現有實現類的前提下添加新方法。集合框架急需 `forEach`、`stream` 等方法,但不能強制所有 `Collection` 實現類 (ArrayList, HashSet, 第三方庫) 立即實現。默認方法 允許在接口中提供方法實現,實現類可選擇繼承或覆寫,實現接口平滑演進。
public interface Vehicle {
// 默認方法:default 關鍵字 + 方法體
default void start() {
System.out.println("Vehicle starting...");
}
// 靜態方法:接口層級工具方法,不可被實現類覆寫 (可隱藏)
static Vehicle create(String type) {
return switch (type) {
case "car" -> new Car();
case "bike" -> new Bike();
default -> throw new IllegalArgumentException();
};
}
// 抽象方法:仍需實現類實現
void drive();
}
public class Car implements Vehicle {
@Override public void drive() { System.out.println("Car driving"); }
// 繼承了 start(),未覆寫
}
public class Bike implements Vehicle {
@Override public void drive() { System.out.println("Bike riding"); }
@Override public void start() { System.out.println("Bike kick-start"); } // 覆寫
}
類實現多個接口,若多個接口有同名同參數的默認方法,編譯報錯,必須在類中顯式指定調用哪個或提供新實現。
interface A { default void hello() { System.out.println("A"); } }
interface B extends A { default void hello() { System.out.println("B"); A.super.hello(); } } // 可調用父接口默認方法
class C implements B { public static void main(String[] args) { new C().hello(); } }
// 輸出: B -> A
interface D { default void hello() { System.out.println("D"); } }
interface E { default void hello() { System.out.println("E"); } }
class F implements D, E {
// 必須覆寫,否則編譯錯誤: "class F inherits unrelated defaults for hello() from types D and E"
@Override
public void hello() {
D.super.hello(); // 顯式調用 D 的實現
E.super.hello(); // 顯式調用 E 的實現
System.out.println("F own");
}
}
class Base { public void hello() { System.out.println("Base"); } }
interface G { default void hello() { System.out.println("G"); } }
class H extends Base implements G {
// 無衝突!類優先原則:父類實例方法 > 接口默認方法
// H 未覆寫 hello(),調用時執行 Base.hello()
}
| 特性 | 接口默認方法 | 抽象類 |
|---|---|---|
| 構造函數 | 無 | 有 |
| 狀態 (字段) | 無 (只能 static final 常量) | 有 (實例字段) |
| 多實現 | 類可 implements 多個接口 | 單繼承 |
| 訪問修飾符 | 默認 public | 任意 |
| 用途 | 行為擴展、庫演進、組合行為 | 核心領域模型、共享狀態、模板方法 |
InterfaceName.staticMethod() 調用。
// java.util.Collection 接口 (JDK 8+)
public interface Collection extends Iterable {
// 默認方法,默認實現調用 spliterator()
default Stream stream() {
return StreamSupport.stream(spliterator(), false);
}
// 所有實現類 (ArrayList, HashSet, LinkedList...) 免費獲得 stream() 能力!
}
X.super.method() 顯式委派,別拖到運行時。List.of(), Map.of() 等 JDK 9+ 工廠方法即接口靜態方法。Java 8 默認方法 解決了接口演進的「二元悖論」:保持二進制兼容性 的同時賦予新能力。核心規則:類優先於接口、具體覆寫優於默認、菱形衝突必須顯式解決。善用默認方法可構建靈活的行為組合 (如 `Comparator.thenComparing`),但切勿濫用替代抽象類的領域建模職責。