java 子類重寫父類的方法應注意的問題


若想實現一個合格重寫方法,而不是重載,那么必須同時滿足下面的要求!

A、重寫規則之一:
    重寫方法不能比被重寫方法限制有更嚴格的訪問級別
(但是可以更廣泛,比如父類方法是包訪問權限,子類的重寫方法是public訪問權限。) 比如:Object類有個toString()方法,開始重寫這個方法的時候我們總容易忘記public修飾符,編譯器當然不會放過任何教訓我們 的機會。出錯的原因就是:沒有加任何訪問修飾符的方法具有包訪問權限,包訪問權限比public當然要嚴格了,所以編譯器會報錯的。

反正子類寫public就肯定是沒錯的

B、重寫規則之二:
   參數列表必須與被重寫方法的相同。
重寫有個孿生的弟弟叫重載,也就是后面要出場的。如果子類方法的參數與父類對應的方法不同,那么就是你認錯人了,那是重載,不是重寫。     

C、重寫規則之三:
   返回類型必須與被重寫方法的返回類型相同。
父類方法A:void eat(){} 子類方法B:int eat(){} 兩者雖然參數相同,可是返回類型不同,所以不是重寫。
父類方法A:int eat(){} 子類方法B:long eat(){} 返回類型雖然兼容父類,但是不同就是不同,所以不是重寫。

D、重寫規則之四:
   重寫方法不能拋出新的異常或者比被重寫方法聲明的檢查異常更廣的檢查異常。但是可以拋出更少,更有限或者不拋出異常。

 1 import java.io.*;
 2 public class Test {
 3   public static void main (String[] args) {
 4    Animal h = new Horse();
 5    try {
 6      h.eat();
 7    }
 8    catch (Exception e) {
 9    }
10  }
11 }
12 
13 class Animal {
14   public void eat() throws Exception{
15    System.out.println ("Animal is eating.");
16    throw new Exception();
17   }
18 }
19 
20 class Horse extends Animal{
21    public void eat() throws IOException{
22     System.out.println ("Horse is eating.");
23     throw new IOException();
24   }
25 }

 這個例子中,父類拋出了檢查異常Exception,子類拋出的IOException是Exception的子類,也即是比被重寫的方法拋出了更有限的異常,這是可以的。如果反過來,父類拋出IOException,子類拋出更為寬泛的Exception,那么不會通過編譯的。
注意:這種限制只是針對檢查異常,至於運行時異常RuntimeException及其子類不再這個限制之中。

E、重寫規則之五:
   不能重寫被標識為final的方法。

F、重寫規則之六:
  如果一個方法不能被繼承,則不能重寫它。

比較典型的就是父類的private方法。下例會產生一個有趣的現象。
 

 

 1 public class Test {
 2   public static void main (String[] args) {
 3    //Animal h = new Horse();
 4    Horse h = new Horse();
 5     h.eat();
 6    }
 7 }
 8 
 9 class Animal {
10    private void eat(){
11     System.out.println ("Animal is eating.");
12     }
13  }
14 
15 class Horse extends Animal{
16    public void eat(){
17      System.out.println ("Horse is eating.");
18    }
19 }

 

這段代碼是能通過編譯的。表面上看來違反了第六條規則,但實際上那是一點巧合。Animal類的eat()方法不能被繼承,因此Horse類中的 eat()方法是一個全新的方法,不是重寫也不是重載,只是一個只屬於Horse類的全新的方法!這點讓很多人迷惑了,但是也不是那么難以理解。
main()方法如果是這樣:
Animal h = new Horse();
//Horse h = new Horse();
h.eat();
編譯器會報錯,為什么呢?Horse類的eat()方法是public的啊!應該可以調用啊!請牢記,多態只看父類引用的方法,而不看子類對象的方法!

曾志偉的見解如下

多態只看父類引用的方法,而不堪子類對象的方法!什么意思呢?Animal h=new Horse();這個體現了多態,但是h.eat()只會調用子類重寫父類的那個方法,而該demo中因為父類的方法是private的,所以子類無法重寫這個方法,也就是子類那個eat()是子類自己新創建的方法,跟父類沒有半點關系,所以這時候Animal h=new Horse();會報錯

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM