接口是 Java 實現多態、解耦合、契約式編程的核心機制。本文系統講解接口的本質特徵、定義與實現語法、默認/靜態方法演進、多實現機制及在設計模式中的核心應用。
| 特性 | 接口 | 抽象類 |
|---|---|---|
| 方法類型 | 隱式 public abstract(Java 8 前) | 可有具體方法 |
| 字段 | 隱式 public static final(常量) | 可有實例變量 |
| 構造器 | 無 | 有(供子類調用) |
| 繼承關係 | implements,支持多實現 | extends,單繼承 |
| 設計意圖 | 定義契約、行為規範 | 代碼復用、模板方法 |
default 默認方法、static 靜態方法private 私有方法(供默認/靜態方法內部復用)
public interface Calculator {
// 常量(隱式 public static final)
double PI = 3.1415926;
int MAX_VALUE = Integer.MAX_VALUE;
// 抽象方法(隱式 public abstract)
double add(double a, double b);
double subtract(double a, double b);
double multiply(double a, double b);
double divide(double a, double b);
// Java 8+ 默認方法
default double power(double base, int exponent) {
return Math.pow(base, exponent);
}
// Java 8+ 靜態方法
static boolean isValidNumber(double num) {
return !Double.isNaN(num) && !Double.isInfinite(num);
}
// Java 9+ 私有方法
private double validate(double num) {
if (!isValidNumber(num)) throw new ArithmeticException("無效數值");
return num;
}
}
// 接口可多繼承
public interface ScientificCalculator extends Calculator {
double sin(double radian);
double cos(double radian);
double log(double base, double value);
}
public class BasicCalculator implements Calculator {
@Override
public double add(double a, double b) {
return a + b;
}
@Override
public double subtract(double a, double b) {
return a - b;
}
@Override
public double multiply(double a, double b) {
return a * b;
}
@Override
public double divide(double a, double b) {
if (b == 0) throw new ArithmeticException("除數不能為零");
return a / b;
}
}
interface A { default void show() { System.out.println("A"); } }
interface B { default void show() { System.out.println("B"); } }
// 編譯錯誤:繼承了衝突的默認方法
// class C implements A, B {}
// 必須顯式覆蓋解決衝突
class C implements A, B {
@Override
public void show() {
// 可選調用特定接口實現
A.super.show(); // 輸出 A
B.super.show(); // 輸出 B
System.out.println("C 自己的實現");
}
}
interface Base { default void method() { System.out.println("Base"); } }
interface Left extends Base {}
interface Right extends Base {}
class Bottom implements Left, Right {} // OK,只有一個 Base 實現
// 策略接口
interface PaymentStrategy {
void pay(double amount);
}
// 具體策略
class AlipayPayment implements PaymentStrategy {
public void pay(double amount) { System.out.println("支付寶支付:" + amount); }
}
class WechatPayment implements PaymentStrategy {
public void pay(double amount) { System.out.println("微信支付:" + amount); }
}
// 上下文
class PaymentContext {
private PaymentStrategy strategy;
public void setStrategy(PaymentStrategy strategy) { this.strategy = strategy; }
public void executePayment(double amount) { strategy.pay(amount); }
}
interface Shape { void draw(); }
class Circle implements Shape { public void draw() { System.out.println("○"); } }
class Rectangle implements Shape { public void draw() { System.out.println("▭"); } }
class ShapeFactory {
public static Shape createShape(String type) {
return switch (type.toLowerCase()) {
case "circle" -> new Circle();
case "rectangle" -> new Rectangle();
default -> throw new IllegalArgumentException("未知形狀:" + type);
};
}
}
// 高層模塊依賴抽象
interface UserRepository {
User findById(Long id);
void save(User user);
}
// 低層實現
class JpaUserRepository implements UserRepository { /* ... */ }
class RedisUserRepository implements UserRepository { /* ... */ }
// 業務服務依賴接口而非實現
@Service
class UserService {
private final UserRepository repository; // 構造器注入
public UserService(UserRepository repository) { this.repository = repository; }
}
Java 8 引入 @FunctionalInterface 註解,單抽象方法接口可用 Lambda 表達式:
@FunctionalInterface
interface Converter {
T convert(F from);
}
// 使用
Converter toInt = Integer::valueOf;
Integer result = toInt.convert("123"); // 123
// 內置函數式接口
Predicate nonEmpty = s -> s != null && !s.isEmpty();
Function length = String::length;
Consumer printer = System.out::println;
Supplier now = LocalDateTime::now;
enum 或工具類
需要構造器/實例狀態? → 抽象類
需要單繼承代碼復用? → 抽象類
定義跨層級契約? → 接口
支持多實現/多態? → 接口
Java 8+ 需要默認實現? → 接口
函數式編程場景? → 函數式接口
接口是 Java 面向對象設計的基石,善用接口能構建高內聚、低耦合、易擴展的系統架構。理解其演進特性與設計模式應用,是進階 Java 架構師的必備能力。