Java繼承方法隱藏(覆蓋)


方法隱藏

一個類從其超類繼承所有非私有靜態方法。在子類中重新定義繼承的靜態方法稱為方法隱藏。子類中的重定義靜態方法隱藏其超類的靜態方法。在類中重定義非靜態方法稱為方法覆蓋。
關於方法隱藏的重定義方法(名稱,存取級別,返回型別和異常)的所有規則與方法覆蓋相同。

class MySuper {
  public static void print() {
    System.out.println("Inside MySuper.print()");
  }
}

class MySubclass extends MySuper {
  public static void print() {
    System.out.println("Inside MySubclass.print()");
  }
}

public class Main {
  public static void main(String[] args) {
    MySuper mhSuper = new MySubclass();
    MySubclass mhSub = new MySubclass();
    MySuper.print();
    MySubclass.print();
    ((MySuper) mhSub).print();
    mhSuper = mhSub;
    mhSuper.print();
    ((MySubclass) mhSuper).print();
  }
}

上面的程式碼生成以下結果。

Inside MySuper.print()
Inside MySubclass.print()
Inside MySuper.print()
Inside MySuper.print()
Inside MySubclass.print()

欄位隱藏

子類中的欄位宣告(靜態或非靜態),在其父類別中會隱藏具有相同名稱的繼承欄位,也就是說在欄位名稱相同,子類讀取欄位時,只能讀取子類中的欄位無法讀取到父類別中的欄位。
在欄位隱藏的情況下,不考慮欄位的型別及其存取級別。欄位隱藏僅基於欄位名稱。

class MySuper {
  protected int num = 100;
  protected String name = "Tom";
}

class MySub extends MySuper {
  public void print() {
    System.out.println("num: " + num);
    System.out.println("name: " + name);
  }
}

class MySub2 extends MySuper {
  // Hides num field in MySuper class
  private int num = 200;

  // Hides name field in MySuper class
  private String name = "Jack";

  public void print() {
    System.out.println("num: " + num);
    System.out.println("name: " + name);
  }
}

public class Main {
  public static void main(String[] args) {
    MySub fhSub = new MySub();
    fhSub.print();
    MySub2 fhSub2 = new MySub2();
    fhSub2.print();
  }
}

執行上面的程式碼,將會得到如下結果 -

num: 100
name: Tom
num: 200
name: Jack

範例

以下程式碼顯示了如何使用 super 關鍵字存取超類中的隱藏欄位。

class MySuper {
  protected int num = 100;
  protected String name = "Tom";
}

class MySub extends MySuper {
  // Hides the num field in MySuper class
  private int num = 200;

  // Hides the name field in MySuper class
  private String name = "Jack";

  public void print() {
    System.out.println("num: " + num);
    System.out.println("super.num: " + super.num);
    System.out.println("name: " + name);
    System.out.println("super.name: " + super.name);
  }
}

public class Main {
  public static void main(String[] args) {
    MySub s = new MySub();
    s.print();
  }
}

上面的程式碼生成以下結果。

num: 200
super.num: 100
name: Jack
super.name: Tom

欄位隱藏發生在一個類宣告一個變數與來自其繼承超類中的變數的名稱相同時。欄位隱藏僅基於欄位的名稱。子類可使用關鍵字super來存取超類的隱藏欄位。子類可以使用簡單的名稱來存取其主體中的重定義的欄位。