介面、多態、內部類是 Java 面向對象三大支柱,共同支撐起靈活、可擴展、低耦合的系統架構。本文從語言機制、設計哲學、實戰模式三個維度深度剖析。
interface Flyable {
// 隱含 public static final
int MAX_HEIGHT = 10000;
// 隱含 public abstract
void fly();
// JDK 8+ 默認方法
default void land() { System.out.println("降落"); }
// JDK 8+ 靜態方法
static Flyable create() { return new Bird(); }
}
class A implements I1, I2, I3| 維度 | 介面 | 抽象類 |
|---|---|---|
| 關系語義 | like-a(擁有某能力) | is-a(屬於某體系) |
| 定義內容 | 行為規範(方法簽名) | 屬性+行為(可含實現) |
| 多重實現 | 支援多介面 | 單繼承 |
| 演進成本 | 高(所有實現需修改) | 低(可加默認實現) |
原則:優先用介面定義契約,需共享狀態/邏輯時引入抽象類。
Animal a = new Cat(); // 向上轉型:父類引用指向子類對象
a.eat(); // 動態綁定:調用 Cat.eat()
// 向下轉型(需 instanceof 守護)
if (a instanceof Cat) {
Cat c = (Cat) a;
c.catchMouse(); // 訪問子類特有方法
}
| 成員類型 | 編譯期綁定 | 運行期綁定 | 口訣 |
|---|---|---|---|
| 實例變量 | 引用類型 | 引用類型 | 編譯看左,運行看左 |
| 實例方法 | 引用類型 | 對象實際類型 | 編譯看左,運行看右 |
| 靜態方法 | 引用類型 | 引用類型 | 編譯看左,運行看左 |
if (a instanceof Cat c) { // 直接宣告並賦值
c.catchMouse();
}
| 類型 | 定義位置 | 訪問外部成員 | 實例化方式 | 典型場景 |
|---|---|---|---|---|
| 成員內部類 | 類內、方法外 | 全部(含 private) | outer.new Inner() | 狀態綁定邏輯 |
| 靜態內部類 | 類內、static 修飾 | 僅 static 成員 | new Outer.Inner() | 單例持有者、Builder |
| 局部內部類 | 方法/塊內 | final/實際 final 變量 | 方法內 new | 臨時邏輯封裝 |
| 匿名內部類 | 表達式中 | 同局部類 | new Interface() {} | 回調、事件監聽 |
interface Reader { void read(); }
interface Writer { void write(); }
class Device {
// 兩個內部類分別實現不同介面
class USBReader implements Reader { public void read() {} }
class USBWriter implements Writer { public void write() {} }
public Reader getReader() { return new USBReader(); }
public Writer getWriter() { return new USBWriter(); }
}
外部類單繼承限制下,內部類各自繼承/實現不同體系,完美解決多重繼承需求。
interface Strategy { void execute(); }
class Context {
public void run(Strategy s) { s.execute(); }
}
// 使用匿名內部類動態注入策略
new Context().run(new Strategy() {
@Override public void execute() { System.out.println("策略A"); }
});