首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 成員變數隱藏與方法覆寫的關鍵差異

     編輯:Java 相關知識

程式碼範例

class Base {
    int a = 10;
    public void show() {
        System.out.println(a);
    }
}
class Ext extends Base {
    int a = 200;
    public void show(String s) {
        System.out.println(s);
    }
}
public class MyMain {
    public static void main(String[] argv) {
        Ext obj = new Ext();
        obj.show();      // 輸出 10
        obj.show("OK");  // 輸出 OK
    }
}

核心觀念:變數隱藏 ≠ 方法覆寫

成員變數(欄位)不支援多型,它們在編譯期靜態解析;方法在執行期動態分派。子類別定義同名欄位時,會隱藏父類別的同名欄位,而非覆寫。

經典範例解析

class S1 {
    public String s = "S1";
    public String getS() { return s; }
}
class S2 extends S1 {
    public String s = "S2";
    public String getS() { return s; }
}
public class Shadow {
    public static void main(String[] args) {
        S1 s1 = new S1();
        S2 s2 = new S2();
        System.out.println(s1.s);        // S1
        System.out.println(s1.getS());   // S1
        System.out.println(s2.s);        // S2
        System.out.println(s2.getS());   // S2
        s1 = s2;                         // 父類別參考指向子類別物件
        System.out.println(s1.s);        // S1 —— 編譯期看型別 S1
        System.out.println(s1.getS());   // S2 —— 執行期看實際物件 S2
    }
}

關鍵點總結

  • s1.s 存取的是 S1 宣告的欄位,因為變數型別是 S1,編譯期綁定
  • s1.getS() 呼叫的是 S2 覆寫的方法,執行期動態分派,存取 S2 的 s
  • 直接存取欄位永遠看參考變數的宣告型別;呼叫方法看實際物件的型別
  • 若需多型行為,請改用 getter/setter 方法封裝欄位

最佳實務建議

  1. 盡量將欄位宣告為 private,提供公開的存取方法
  2. 避免在子類別定義與父類別同名的欄位,防止混淆
  3. 理解「隱藏」與「覆寫」的差異,正確預測程式行為
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved