子類重寫父類方法注意
子類重寫父類的方法應注意的問題
若想實現一個合格重寫方法,而不是過載,那麼必須同時滿足下面的要求!
重寫規則之一:重寫方法不能比被重寫方法限制有更嚴格的訪問級別。
(但是可以更廣泛,比如父類方法是包訪問許可權,子類的重寫方法是public訪問許可權。)比如:Object類有個toString()方法,開始重寫這個方法的時候我們總容易忘記public修飾符,編譯器當然不會放過任何教訓我們的機會。出錯的原因就是:沒有加任何訪問修飾符的方法具有包訪問許可權,包訪問許可權比public當然要嚴格了,所以編譯器會報錯的。
重寫規則之二: 引數列表必須與被重寫方法的相同。
重寫有個孿生的弟弟叫過載,也就是後面要出場的。如果子類方法的引數與父類對應的方法不同,那麼就是你認錯人了,那是過載,不是重寫。
重寫規則之三:返回型別必須與被重寫方法的返回型別相同。
父類方法A:void eat(){} 子類方法B:int eat(){}兩者雖然引數相同,可是返回型別不同,所以不是重寫。
父類方法A:int eat(){} 子類方法B:long eat(){}返回型別雖然相容父類,但是不同就是不同,所以不是重寫。
重寫規則之四:重寫方法不能丟擲新的異常或者比被重寫方法宣告的檢查異常更廣的檢查異常。但是可以丟擲更少,更有限或者不丟擲異常。
注意:這種限制只是針對檢查異常,至於執行時異常RuntimeException及其子類不再這個限制之中。
重寫規則之五: 不能重寫被標識為final的方法。
重寫規則之六:
比較典型的就是父類的private方法。下例會產生一個有趣的現象。
public class Test {
public static void main(String[] args) {
//Animal h =new Horse();
Horse h = newHorse();
h.eat();
}
}
class Animal {
private voideat(){
System.out.println("Animal is eating.");
}
}
class Horse extends Animal{
public voideat(){
System.out.println("Horse is eating.");
}
}
這段程式碼是能通過編譯的。表面上看來違反了第六條規則,但實際上那是一點巧合。Animal類的eat()方法不能被繼承,因此Horse類中的eat()方法是一個全新的方法,不是重寫也不是過載,只是一個只屬於Horse類的全新的方法!這點讓很多人迷惑了,但是也不是那麼難以理解。
main()方法如果是這樣:
Animal h = new Horse();
//Horse h = new Horse();
h.eat();
編譯器會報錯,為什麼呢?Horse類的eat()方法是public的啊!應該可以呼叫啊!請牢記,多型只看父類引用的方法,而不看子類物件的方法!
重寫規則之七:子類不能用 靜態方法 重寫父類的非靜態方法
編繹無法通過this static method cannot hide the instance mehtodfrom
class A {
protected int method1(int a,int b) {
return 0;
}
}
public class Test1 extends A {
private int method1(int a, long b) {
return 0;
}
//this static method cannot hide the instance mehtod from A
static public int method1(inta, int b) {
return 0;
}
}
重寫規則之八:子類不能用非靜態方法 重寫 父類的靜態方法