Java 規定子類不繼承父類的 `private` 字段,但 `new Child()` 時,堆上的子類對象是否為父類 `private` 字段分配內存?若不分配,子類調用繼承的 `public getA()` 時如何讀取到父類 `private int a` 的值?
子類實例在堆中完整包含父類所有非靜態字段(包括 private),只是編譯器禁止子類代碼直接按名訪問。 內存佈局中父類字段與子類字段連續存放,訪問通過父類的公共方法間接實現。
Child 對象內存結構:
+------------------+
| Father 部分 |
| - private int a | <-- 佔用 4 字節
| - private int b |
| - private int c |
+------------------+
| Child 部分 |
| - private int c | <-- 子類自己的 c,覆蓋概念僅在編譯期
+------------------+
class Father {
private int a = 3;
private int b = 3;
private int c = 3;
public Father(int b) { this.b = b; }
public int getA() { return a; }
public void setA(int a) { this.a = a; }
// ... 其他 getter/setter
}
class Child extends Father {
private int c; // 子類自己的 c
public Child() { super(0); }
public Child(int b, int c) { super(b); this.c = c; }
public int getC() { return c; } // 返回子類的 c
// 未重寫 getA(),繼承父類的 getA()
}
public static void main(String[] args) {
Child c1 = new Child();
Child c2 = new Child(3, 5);
System.out.println("c1.a=" + c1.getA() + " c1.b=" + c1.getB() + " c1.c=" + c1.getC());
// 輸出: c1.a=3 c1.b=0 c1.c=0
c2.setA(4);
c2.setC(c2.getC() + 1);
System.out.println("c2.a=" + c2.getA() + " c2.c=" + c2.getC());
// 輸出: c2.a=4 c2.c=6
}
調用 `c2.getA()` 時:
整過程**無需在棧中創建局部變量副本**;`a` 始終駐留在堆對象內存中。
《Java Language Specification》§8.2: "The non-private fields, methods, and constructors of a class are inherited by its subclasses... Private members are not inherited."
「不繼承」僅指**編譯期可見性**,不代表**運行期內存不存在**。