許多開發者誤以為接口是為彌補 Java 無多重繼承而生。實則接口與繼承本質不同:接口定義「類型」(Type),繼承定義「實現共享」(Implementation Sharing)。接口標識類具備某種能力或契約,而非提供代碼復用。
// 1. 定義契約
public interface DB {
Connection open(String url, String user, String pwd);
void close();
}
// 2. 多種實現
public class MySQLDB implements DB { /* ... */ }
public class OracleDB implements DB { /* ... */ }
// 3. 工廠封裝實例化邏輯
public class DBFactory {
public static DB getConnection() {
// 可從配置讀取、環境變量、SPI 等動態決定
return new MySQLDB();
}
}
// 4. 客戶端代碼零耦合具體實現
DB db = DBFactory.getConnection();
db.open(url, user, pwd);
此即「普通工廠模式」。若需進一步解耦工廠本身,可引入 DBFactory 接口與多種工廠實現,演變為「抽象工廠模式」。
《Design Patterns》反覆強調:Favor composition over inheritance。若 B 需要 A 的 run(),應組合 A 實例並委派,而非 class B extends A:
class B {
private final A a = new A();
void run() { a.run(); } // 委派
}
繼承僅適用於「is-a」且需擴展/修改父類行為的「抽象類」場景。抽象類不可實例化,純粹作為模板,這正是繼承的正確語義。
Java 取消多重繼承正是為遏制此類濫用,迫使開發者轉向接口組合與委派。