Java覆蓋/重載
在前麵的章節中,我們談到了超類和子類。如果一個類從它的超類繼承的方法,則有機會改寫,隻要它不標記為final的方法。
重載的好處是:定義一個行為是特定於該子類的類型表示一個子類可以實現根據它要求一個父類的方法的能力。
在麵向對象的術語,重載表示覆蓋現有的方法的功能。
例子:
讓我們來看一個例子。
class Animal{ public void move(){ System.out.println("Animals can move"); } } class Dog extends Animal{ public void move(){ System.out.println("Dogs can walk and run"); } } public class TestDog{ public static void main(String args[]){ Animal a = new Animal(); // Animal reference and object Animal b = new Dog(); // Animal reference but Dog object a.move();// runs the method in Animal class b.move();//Runs the method in Dog class } }
這將產生以下結果:
Animals can move Dogs can walk and run
在上麵的例子中,可以看到,即使b為一類動物的並運行在狗類中的move方法。這樣做的原因是:在編譯時,檢查是在引用類型。然而,在運行時,JVM計算出的對象類型和運行將屬於特定對象的方法。
因此,在上麵的例子中,程序將正確編譯,因為動物類有法之舉。然後,在運行時,它運行的方法,具體用於該對象。
請看下麵的例子:
class Animal{ public void move(){ System.out.println("Animals can move"); } } class Dog extends Animal{ public void move(){ System.out.println("Dogs can walk and run"); } public void bark(){ System.out.println("Dogs can bark"); } } public class TestDog{ public static void main(String args[]){ Animal a = new Animal(); // Animal reference and object Animal b = new Dog(); // Animal reference but Dog object a.move();// runs the method in Animal class b.move();//Runs the method in Dog class b.bark(); } }
這將產生以下結果:
TestDog.java:30: cannot find symbol symbol : method bark() location: class Animal b.bark(); ^
這個程序將拋出一個編譯時錯誤,因為B的引用類型的動物冇有一種方法,通過bark的名字。
規則方法重載:
-
參數列表應該是完全一樣被覆蓋的方法。
-
返回類型應相同或超類中的原重寫的方法聲明的返回類型的子類型。
-
訪問級彆不能比被重寫的方法的訪問級彆更嚴格。例如:如果父類方法聲明為public,在子類中重寫的方法不能是private或protected。
-
實例方法可以被覆蓋,隻有當他們是由子類繼承。
-
方法聲明為final不能被重寫。
-
方法聲明為靜態的不能被覆蓋,但可以重新聲明。
-
如果一個方法不能被繼承,那麼它不能被重寫。
-
作為實例的父類在同一個包內的子類可以重寫未聲明為私有的或最終的任何超類方法。
-
在不同的包中的子類隻能重寫非final方法聲明為public或protected。
-
重寫方法可以拋出任何異常取消勾選,無論重寫的方法是否拋出異常與否。但壓倒一切的方法不應該拋出checked exceptions新的或不是由重寫的方法聲明的那些更廣泛。重寫方法可以拋出比重寫的方法較窄或更少的例外。
-
構造函數不能被重寫。
使用super關鍵字:
當調用一個重載方法的超類版本,那麼需要使用super關鍵字。
class Animal{ public void move(){ System.out.println("Animals can move"); } } class Dog extends Animal{ public void move(){ super.move(); // invokes the super class method System.out.println("Dogs can walk and run"); } } public class TestDog{ public static void main(String args[]){ Animal b = new Dog(); // Animal reference but Dog object b.move(); //Runs the method in Dog class } }
這將產生以下結果:
Animals can move Dogs can walk and run