子類不能重寫父類的靜態方法,私有方法。即使你看到子類中存在貌似是重寫的父類的靜態方法或者私有方法,編譯是沒有問題的,但那其實是你重新又定義的方法,不是重寫。具體有關重寫父類方法的規則如下:
重寫規則之一:
重寫方法不能比被重寫方法限制有更嚴格的訪問級別。
但是可以更廣泛,比如父類方法是包訪問權限,子類的重寫方法是public訪問權限。有個人曾經這樣說:父類為protected的,子類重寫時一定要用public;我覺得這個觀點不能是絕對的,只要滿足子類的訪問權限不比父類低就行了。
比如:Object類有個toString()方法,開始重寫這個方法的時候我們總容易忘記public修飾符,編譯器當然不會放過任何教訓我們的機會。出錯的原因就是:沒有加任何訪問修飾符的方法具有包訪問權限,包訪問權限比public當然要嚴格了,所以編譯器會報錯的。
重寫規則之二:
參數列表必須與被重寫方法的相同。
重寫有個孿生的弟弟叫重載,也就是后面要出場的。如果子類方法的參數與父類對應的方法不同,那么就是你認錯人了,那是重載,不是重寫。
重寫規則之三:
返回類型必須與被重寫方法的返回類型相同。
父類方法A:void eat(){} 子類方法B:int eat(){}兩者雖然參數相同,可是返回類型不同,所以不是重寫。
父類方法A:int eat(){} 子類方法B:long eat(){}返回類型雖然兼容父類,但是不同就是不同,所以不是重寫。
重寫規則之四:
重寫方法不能拋出新的異常或者比被重寫方法聲明的檢查異常更廣的檢查異常。但是可以拋出更少,更有限或者不拋出異常。
注意:這種限制只是針對檢查異常,至於運行時異常RuntimeException及其子類不再這個限制之中。
重寫規則之五:
不能重寫被標識為final的方法。
重寫規則之六:
如果一個方法不能被繼承,則不能重寫它。如private方法
比較典型的就是父類的private方法。下例會產生一個有趣的現象。
public class Test { public static void main (String[] args) { //Animal h = new Horse(); Horse h = new Horse(); h.eat(); } } class Animal { private void eat(){ System.out.println ("Animal is eating."); } } class Horse extends Animal{ public void eat(){ 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(int a, int b) { return 0; } }
重寫規則之八:
子類不能用非靜態方法重寫父類的靜態方法
編繹報錯:thisinstance method cannot override the static mehtod fromA
class A { protected static 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 //this instance method cannot override the static mehtod from A public int method1(int a, int b) { return 0; } }
總結:
- 在Java中靜態方法可以被繼承,但是不能被覆蓋,即不能重寫。
- 如果子類中也含有一個返回類型、方法名、參數列表均與之相同的靜態方法,那么該子類實際上只是將父類中的該同名方法進行了隱藏,而非重寫。
- 父類引用指向子類對象時,只會調用父類的靜態方法。所以,它們的行為也並不具有多態性。
參考:
http://blog.csdn.net/heshuangyuan123/article/details/38896329(以上內容轉自此篇文章)