Java方法覆蓋教學

方法覆蓋

重新定義來自超類(父類)繼承的類中的實例方法稱爲方法覆蓋。

示例

現在來看看,類A和類B的以下聲明,覆蓋了 print() 方法 :

public class A  {
    public void  print() { 
        System.out.println("A");
    }
}

public class B  extends A  {
    public void  print() { 
        System.out.println("B");
    }
}

B是類A的子類。類B從其超類繼承print()方法並重新定義它。類B中的print()方法覆蓋類Aprint()方法。

如果一個類覆蓋了一個方法,它會影響覆蓋的類及其子類。 考慮下面的類C的聲明:

public class C  extends B  {
   // Inherits B.print()
}

C不聲明任何方法。但它繼承類B中的print()方法。看看下面的代碼,猜想它輸出結果應該是什麼?

class A {
    public void print() {
        System.out.println("A");
    }
}

class B extends A {
    public void print() {
        System.out.println("B");
    }
}

class C extends B {
    public void print() {
        System.out.println("B");
    }
}

public class Main {
    public static void main(String[] args) {
        // Create an object of the Manager class
        A aObj = new A();
        B bObj = new B();
        C cObj = new C();
        aObj.print();
        bObj.print();
        cObj.print();
    }
}

執行上面的代碼,得到以下輸出結果 -

A
B
B

注意, 類總是繼承它的直接超類的方法。

方法必須是實例方法。 覆蓋不適用於靜態方法。重寫方法必須具有與重寫方法相同的名稱。重寫方法必須具有與重寫方法相同順序的相同類型和相同數量的參數。

當方法的參數使用通用類型時,與其他方法比較時考慮將泛型類型參數的擦除。參數的名稱是無關緊要的,不會影響方法的覆蓋。

訪問級別

覆蓋方法的訪問級別必須至少與被覆蓋方法的訪問級別相同或更寬鬆。下表列出了覆蓋方法允許的訪問級別 -

覆蓋方法訪問級別

允許覆蓋方法訪問級別

public

public

protected

public, protected

package-level

public, protected, package-level

方法可以在其throws子句中包括檢查異常的列表。覆蓋方法無法向覆蓋方法中的異常列表添加新的異常。

它可以刪除一個或所有異常,或者可以用另一個異常替換異常。

訪問覆蓋方法

從子類訪問重寫的方法。在子類中可以使用關鍵字super作爲限定符來調用超類的重寫方法。

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

class MySubClass extends MySuperClass {
  public void print() {
    // Call print() method of MySuperClass class
    super.print();
    // Print a message
    System.out.println("Inside MySubClass.print()");
  }

  public void callOverridenPrint() {
    // Call print() method of MySuperClass class 
    super.print();
  }
}

public class Main {
  public static void main(String[] args) {
    MySubClass aoSub = new MySubClass();
    aoSub.print();
    aoSub.callOverridenPrint();
  }
}

上面的代碼生成以下結果。

Inside MySuperClass
Inside MySubClass.print()
Inside MySuperClass