重新定義來自超類(父類別)繼承的類中的範例方法稱為方法覆蓋。
現在來看看,類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()
方法覆蓋類A
的print()
方法。
如果一個類覆蓋了一個方法,它會影響覆蓋的類及其子類。 考慮下面的類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