子類定義與父類同名字段時,字段不參與多態,調用父類繼承的方法訪問的是父類字段。本文通過代碼演示這一核心機制。
class Fu { int x = 7; void a() { System.out.println(this.x); } }
class Zi extends Fu { int x = 6; }
public class Test { public static void main(String[] args) { new Zi().a(); } }
// 輸出:7 (而非 6)
Zi.x 隱藏了 Fu.x,實際上 Zi 對象內存中有兩個 x:Fu.x=7 和 Zi.x=6。Zi 未重寫 a(),調用的是 Fu.a()。Fu.a() 中的 this.x 在編譯期綁定為 Fu.x(聲明類型為 Fu)。Zi 對象內存:
+------------------+
| Fu 部分 |
| x = 7 ← Fu.a() 訪問此處 |
+------------------+
| Zi 部分 |
| x = 6 ← Zi 實例直接訪問此處 |
+------------------+
class Zi extends Fu {
int x = 6;
@Override void a() { System.out.println(this.x); } // 訪問 Zi.x → 輸出 6
}
class Zi extends Fu {
Zi() { this.x = 6; } // 修改 Fu.x
// 不聲明新 x
}
class Fu {
private int x = 7;
public int getX() { return x; }
void a() { System.out.println(getX()); } // 動態綁定
}
class Zi extends Fu {
private int x = 6;
@Override public int getX() { return x; }
}
// new Zi().a() → 輸出 6
| 特性 | 字段 | 方法 |
|---|---|---|
| 多態性 | 無(靜態綁定) | 有(動態綁定) |
| 同名機制 | 隱藏 | 重寫 |
| 訪問方式 | 編譯期看引用類型 | 運行期看對象類型 |
| 最佳實踐 | 私有化 + Getter/Setter | @Override 註解 |
理解「字段隱藏 ≠ 方法重寫」,避免在繼承體系中直接暴露字段,是寫出健壯 Java 代碼的基礎。