通過程式碼例項深入解析Java重寫和過載
過載(Overloading)和重寫(Overriding)是Java中兩個比較重要的概念。但是對於新手來說也比較容易混淆。本文通過兩個簡單的例子說明了他們之間的區別。
定義
過載
簡單說,就是函式或者方法有同樣的名稱,但是引數列表不相同的情形,這樣的同名不同引數的函式或者方法之間,互相稱之為過載函式或者方法。
重寫
重寫指的是在Java的子類與父類中有兩個名稱、引數列表都相同的方法的情況。由於他們具有相同的方法簽名,所以子類中的新方法將覆蓋父類中原有的方法。
過載 VS 重寫
關於過載和重寫,你應該知道以下幾點:
1、過載是一個編譯期概念、重寫是一個執行期間概念。
2、過載遵循所謂“編譯期繫結”,即在編譯時根據引數變數的型別判斷應該呼叫哪個方法。
3、重寫遵循所謂“執行期繫結”,即在執行的時候,根據引用變數所指向的實際物件的型別來呼叫方法
4、因為在編譯期已經確定呼叫哪個方法,所以過載並不是多型。而重寫是多型。過載只是一種語言特性,是一種語法規則,與多型無關,與面向物件也無關。(注:嚴格來說,過載是編譯時多型,即靜態多型。但是,Java中提到的多型,在不特別說明的情況下都指動態多型)
重寫的例子
下面是一個重寫的例子,看完程式碼之後不妨猜測一下輸出結果:
class Dog{ public void bark(){ System.out.println("woof "); } } class Hound extends Dog{ public void sniff(){ System.out.println("sniff "); } public void bark(){ System.out.println("bowl"); } } public class OverridingTest{ public static void main(String [] args){ Dog dog = new Hound(); dog.bark(); } }
輸出結果:
bowl
上面的例子中,dog物件被定義為Dog型別。在編譯期,編譯器會檢查Dog類中是否有可訪問的bark()方法,只要其中包含bark()方法,那麼就可以編譯通過。在執行期,Hound物件被new出來,並賦值給dog變數,這時,JVM是明確的知道dog變數指向的其實是Hound物件的引用。所以,當dog呼叫bark()方法的時候,就會呼叫Hound類中定義的bark()方法。這就是所謂的動態多型性。
重寫的條件
引數列表必須完全與被重寫方法的相同;
返回型別必須完全與被重寫方法的返回型別相同;
訪問級別的限制性一定不能比被重寫方法的強;
訪問級別的限制性可以比被重寫方法的弱;
重寫方法一定不能丟擲新的檢查異常或比被重寫的方法宣告的檢查異常更廣泛的檢查異常
重寫的方法能夠丟擲更少或更有限的異常(也就是說,被重寫的方法聲明瞭異常,但重寫的方法可以什麼也不宣告)
不能重寫被標示為final的方法;
如果不能繼承一個方法,則不能重寫這個方法。
過載的例子
class Dog{ public void bark(){ System.out.println("woof "); } //overloading method public void bark(int num){ for(int i=0; i<num; i++) System.out.println("woof "); } }
上面的程式碼中,定義了兩個bark方法,一個是沒有引數的bark方法,另外一個是包含一個int型別引數的bark方法。在編譯期,編譯期可以根據方法簽名(方法名和引數情況)情況確定哪個方法被呼叫。
過載的條件
被過載的方法必須改變引數列表;
被過載的方法可以改變返回型別;
被過載的方法可以改變訪問修飾符;
被過載的方法可以宣告新的或更廣的檢查異常;
方法能夠在同一個類中或者在一個子類中被過載。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。