內部類核心價值
- 邏輯分組:將屬於同一概念的類組織在一起
- 可見性控制:精細控制內部類對外部類成員的訪問權限
- 隱式引用:內部類實例持有外部類實例引用,可直接訪問外部類所有成員(含
private)
創建內部類
- 在外部類內部定義類
- 外部類方法返回內部類引用(常見模式)
- 外部類非靜態方法外創建需用
OuterClass.InnerClass 語法
內部類與外部類的連結機制
- 內部類對象隱式持有創建它的外部類對象引用
- 訪問外部類成員時自動使用該引用
- 非靜態內部類對象只能在外部類對象關聯下創建
OuterClass.this 獲取外部類引用;outerObj.new InnerClass() 通過外部對象創建內部對象
內部類與向上轉型
- 普通類不可
private/protected,內部類可——實現徹底封裝
private 內部類阻斷類型編碼依賴,隱藏實現細節
- 向上轉型為基類/接口引用,客戶端代碼與具體實現解耦
方法與作用域內的內部類
- 可在方法內、任意代碼塊內定義
- 局部內部類無訪問修飾符,可訪問
final/實際最終變量及外部類成員
- 匿名內部類:
new Interface/Class() { ... } 現場創建實現類對象
匿名內部類關鍵點
- 語義:創建繼承自指定類/實現指定接口的匿名類對象
- 構造器參數直接傳給父類構造器
- 結尾分號屬於包含表達式,非類體結束
- 使用外部變量需
final(Java 8+ 實際最終即可)
- 實例初始化塊替代構造器(僅一個)
- 只能繼承一個類或實現一個接口,不可兼有
工廠方法模式重訪
傾向使用類而非接口;僅在設計確需多態時引入接口。
嵌套類(靜態內部類)
- 無需外部類對象即可創建
- 無法訪問非靜態外部類成員
- 可包含
static 字段/方法/嵌套類
- 類比
static 方法,無特殊 this 引用
接口內的類
- 接口內定義的類自動
public static
- 可實現外部接口,便於為所有實現提供公共代碼
- 適合存放測試代碼
多層嵌套類的外部訪問
無論嵌套多深,內部類均可透明訪問所有外層類成員。
為什麼需要內部類?
- 內部類繼承/實現接口,操作創建它的外部類對象——提供「窗口」
- 區別於外部類實現接口:有時需配合具體實現而非純接口
- 每個內部類可獨立繼承一個實現 → 實現多實現繼承(突破單繼承限制)
- 若基類為抽象/具體類而非接口,內部類成為實現多重協作的唯一途徑
閉包與回調
- 閉包:保留創建作用域信息的可調用對象
- 內部類 = 面向對象閉包,可操作所有成員(含
private)
- 回調:將信息傳給他物,稍後回調源對象
- 指針回調不安全;內部類閉包更靈活、安全
- 創建內部類不修改外部類接口
- 回調價值:運行時動態決定調用方法
內部類與控制框架
- 應用框架典型模式:繼承基類、覆寫方法
- GUI 事件驅動是典型場景
- 內部類允許單類內定義多個同基類(如
Event)的衍生版本
- 近似多重繼承效果,更優雅描述 GUI 行為
- 從文件讀取事件優於硬編碼
繼承內部類
需顯式初始化「秘密」外部類引用,使用特殊語法:OuterClass.InnerClass 構造器調用 outerRef.super()。
內部類可被覆寫嗎?
「覆寫」內部類無實際意義——派生類內部類與基類內部類屬於完全獨立命名空間的不同實體。
局部內部類
- 無訪問修飾符,可訪問當前代碼塊
final 變量及外部類所有成員
- 可有命名構造器/重載構造器(匿名類只有實例初始化)
- 僅當需要命名/重載構造器時選擇局部類,否則匿名類更簡潔
內部類標識符
- 每個類生成
.class 文件,內部類命名:Outer$Inner.class
- 匿名內部類編譯器自動生成數字標識:
Outer$1.class