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來訪問超類的隱藏字段。子類可以使用簡單的名稱來訪問其主體中的重定義的字段。