Java面向對象編程之繼承(二)
阿新 • • 發佈:2017-07-31
抽象方法 oid 修飾 屬於 ... 方法的參數 要求 ring 覆蓋
在上一篇博客中,我們已經了解繼承的基本概念和語法,那麽今天我們就來聊一聊有關於繼承的其他東西。
讓我們來了解一下什麽是方法重載(overload)和方法覆蓋(override)
方法重載(overload)
對於類的的方法(包括從父類中繼承的方法),如果有兩個方法的方法名相同,但參數不一致,那麽可以說,一個方法是另一個方法的重載方法。
重載方法必須滿足以下條件:
- 方法名相同
- 方法的參數類型、個數、順序至少有一項不相同
- 方法的返回類型可以不相同
- 方法的修飾符可以不相同
其中,參數的類型、個數和順序被統稱為參數簽名。來看一下例子:
public class Example{ publicvoid amethod(int i ,String s){} //實例方法 // 加入其它方法 public void amethod(int i,String s){} //不可以,因為這個方法和我們定義的實例方法一模一樣,Java虛擬機在執行時不知道該執行哪一個 public void amethod(String s,int i){} //可以,屬於重載方法,參數的順序不一樣 public int amethod(int i,String s){return 0;} //不可以,雖然方法的返回類型不相同,但是方法名和參數簽名完全一致,所以這不能算是重載方法,不能加到Example中public private amethod(int i,String mystring){} //不可以,方法名和參數簽名相同,所以這也不能算是重載方法 public void Amethod(int i,String s){} //方法名不一樣,是一個新的實例方法,所以可以加入到Example類中 abstract void amethod(int i){} //不可以,該方法的參數數目和已有的不一樣,所以是一種重載方法。但是Example類不是抽象類,所有不能加入這個抽象方法。倘若將Example類改為抽象類。則可以加入這個方法 }
另外,作為程序入口的main()方法也可以被重載。
方法覆蓋(override)
如果子類中定義的一個方法,其名稱、返回類型及參數簽名正好與父類中某個方法的名稱、返回類型及參數簽名相匹配,那麽可以說,子類的方法覆蓋了父類的方法。
覆蓋方法必須滿足多種約束,下面分別介紹:
- 子類方法的名稱、參數簽名和返回類型必須與父類方法的名稱、參數簽名和返回類型一致。
- 子類方法不能縮小父類方法的訪問權限,這是什麽意思呢?我們可以看下面這個例子:
public class A extends B{ private void method(){} //編譯錯誤,子類方法縮小了父類方法的訪問權限 } class B{ public void method(){} }
子類的method()方法是私有的,父類中的method()方法是公有的,子類縮小了父類方法的訪問權限,這是無效的方法覆蓋,會導致編譯錯誤。
- 子類方法不能拋出比父類方法更多的異常。子類方法拋出的異常必須和父類方法拋出的異常相同,或者是父類方法拋出的異常的子集。
- 方法覆蓋只存在於子類和父類(包括直接父類和間接父類)之間,在同一個類中方法只能被重載,不能被覆蓋。
- 父類的靜態方法不能被子類覆蓋為非靜態方法。
- 子類可以定義同父類的靜態方法同名的靜態方法,以便在子類中隱藏父類的靜態方法。在編譯時,子類定義的靜態方法也必須滿足和方法覆蓋類似的約束:方法的參數簽名一致,返回類型一致,不能縮小父類方法的訪問權限,不能拋出更多的異常。
- 父類的非靜態方法不能被子類覆蓋為靜態方法。
- 父類的私有方法不能被子類覆蓋。
- 父類的抽象方法可以被子類通過兩種途徑覆蓋:一是子類實現父類的抽象方法;二是子類重新聲明父類的抽象方法。例如以下代碼合法:
abstract class Base(){ abstract void method1(); abstract void method2(); } public abstract class Sub extends Base(){ public void method1(){...}; //實現method1()方法,並且擴大訪問範圍 public abstract method2(){}; //重新聲明method2()方法,僅僅擴大訪問權限,但不實現 }
10.父類的非抽象方法可以被覆蓋為抽象方法。
狹義地理解,覆蓋僅指子類覆蓋父類的具體方法,即非抽象方法,在父類中提供了方法的默認實現方式,而子類采用不同的實現方式。
方法覆蓋與方法重載的異同
方法覆蓋和方法重載具有以下相同點:
- 都要求方法同名。
- 都可以用於抽象方法和非抽象方法之間。
方法覆蓋和方法重載具有以下不同點:
- 方法覆蓋要求參數簽名必須一致,而方法重載要求參數簽名必須不一致。
- 方法覆蓋要求返回類型必須一致,而方法重載對此不作限制。
- 方法覆蓋只能用於子類繼承父類的方法,方法重載用於同一個類的所有方法,包括從父類中繼承而來的方法。
- 方法覆蓋對方法的訪問權限和拋出的異常有特殊的要求,而方法重載在這方面沒有限制。
- 父類的一個方法只能被子類覆蓋一次,而一個方法在所在的類中可以被重載多次。
Java面向對象編程之繼承(二)