首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 實現「類多繼承」:內部類組合模式讓 B 同時擁有 C 的方法與 D 的身份

     編輯:程式設計綜合問答

問題場景

  • 類 C 包含 A、B 共用的方法。
  • 類 D 是 SDK 最終類(final),不可繼承/修改。
  • A extends C,B extends D,但 B 也需要 C 的方法 → Java 不支持多重繼承。

解決方案:內部類組合(組合優於繼承)

public class B extends D {
    // 1. 定義內部類繼承 C,獲得 C 的所有非私有方法
    private class InnerC extends C {
        // 可按需重寫或擴展 C 的方法
    }

    // 2. 持有內部類實例
    private final InnerC innerC = new InnerC();

    // 3. 對外暴露委託方法(門面模式)
    public void methodFromC() {
        innerC.methodFromC(); // 轉發調用
    }

    // 若 C 方法較多,可讓 B 實現接口,內部類實現該接口,減少樣板代碼
}

為什麼這樣設計?

方案優點缺點
內部類繼承 C + 委託 繞過 final 限制;封裝性好;可控制暴露哪些方法 需手寫委託方法(可用 IDE 生成/ Lombok @Delegate)
實現接口 + 默認方法 (Java 8+) 無需內部類;接口默認方法提供實現 要求 C 改為接口,或提取公共接口;默認方法無法訪問實例狀態
組合:持有 C 實例 (非繼承) 最鬆耦合;C 可為 final 同樣需委託;若 C 有 protected 成員需子類訪問則不行

進階:Lombok @Delegate 自動生成委託代碼

@RequiredArgsConstructor
public class B extends D {
    @Delegate(types = C.class) // 自動將 C 的公共方法委託給 innerC
    private final C innerC = new C(); // 或 new InnerC()
}

編譯後 Lombok 會為 B 生成所有 C 公共方法的轉發調用,極大減少樣板代碼。

設計原則總結

  1. 組合優於繼承:通過持有對象而非繼承獲取功能。
  2. 接口隔離:定義公共行為接口,C 實現接口,B 通過組合實現同一接口。
  3. 適配器模式:若 D 也是外部類,B 可實現目標接口,內部持有 D 與 C 實例,雙向適配。

適用場景

  • Android:Activity、Fragment 等最終類不可繼承,需複用邏輯類。
  • Spring Bean:最終類無法被 CGLIB 代理,需包裝器模式。
  • SDK 二次開發:核心類封閉,擴展點僅提供接口。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved