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

Java 繼承陷阱:父類方法調用與字段遮蔽導致輸出不符預期

     編輯:程式設計疑難解答

題目代碼邏輯

class TestDemo { // 父類
    int m = 7;
    void some(int x) { m = x; System.out.println(m); }
    public static void main(String[] args) {
        new Demo().some(7); // 調用子類對象的 some(7)
    }
}
class Demo extends TestDemo { // 子類
    int m = 8; // 遮蔽父類 m
    void some(int x) { super.some(x); } // 調用父類 some(7)
}

輸出結果

8(而非預期的 7)

詳細執行流程

  1. main 中創建 Demo 對象,調用 some(7) → 進入 子類 some(int x)。
  2. 子類 some 執行 super.some(x) → 調用 父類 some(int x),參數 x=7。
  3. 父類 some 執行 m = x → 此處 m 是父類的字段,賦值为 7。
  4. 父類 some 執行 System.out.println(m) → 此處 m 發生多態字段訪問? 否!Java 字段不發生多態,編譯期綁定:父類方法中 m 解析為父類字段,但運行時 this 是子類對象,父類字段 m=7,子類字段 m=8。
  5. 關鍵點:父類 some 中的 System.out.println(m) 訪問的是 父類的 m(值為 7)?實際運行卻輸出 8,說明代碼中父類 some 內部訪問的是 this.m,而 this 是子類實例,字段解析遵循「編譯看類型,運行看對象」?
    修正:Java 中字段無多態,父類代碼編譯時綁定父類字段。若輸出 8,說明題目代碼中父類 some 內部寫的是 System.out.println(this.m) 且父類無 m 字段?或題目描述有出入。
    標準行為:父類方法訪問字段 → 父類字段。若子類遮蔽,父類方法仍見父類字段。

最佳實踐

  • 避免字段遮蔽:子類勿定義與父類同名字段。
  • 封裝字段:用 private + getter/setter,子類通過方法間接訪問,實現多態行為。
  • 若需共享狀態,父類字段設為 protected,子類直接使用同一字段。

註:題目截圖代碼未完全可見,以上分析基于典型「字段遮蔽 + 父類方法調用」場景。實際輸出 8 表明父類打印的是子類字段,可能父類無 m 字段或使用反射/特殊上下文。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved