重寫(Override)
重寫是子類對父類的允許通路的方法的實作過程進行重新編寫, 傳回值和形參都不能改變。(即外殼不變,核心重寫!)
重寫的好處在于子類可以根據需要,定義特定于自己的行為。也就是說子類能夠根據需要實作父類的方法。
重寫方法不能抛出新的檢查異常或者比被重寫方法申明更加寬泛的異常。
例如:
父類的一個方法申明了一個檢查異常 IOException,但是在重寫這個方法的時候不能抛出 Exception 異常,因為 Exception 是 IOException 的父類,隻能抛出 IOException 的子類異常。
在面向對象原則裡,重寫意味着可以重寫任何現有方法。
執行個體如下:
pubilc class Animal{
public void move(){
System.out.println("動物可以移動");
}
}
public class Cat extends Animal{
public void move(){
System.out.println(“貓可以跑和走");
}
}
public class TestCat{
public static void main(String args[]){
Animal aa = new Animal(); // Animal 對象
Animal bb = new Cat(); //Cat對象
aa.move();// 執行 Animal 類的方法
bb.move();//執行 Cat 類的方法
}
}
運作結果如圖:

在上面的例子中可以看到,盡管bb屬于Animal類型,但是它運作的是Cat類的move方法。
這是由于在編譯階段,隻是檢查參數的引用類型。
然而在運作時,Java虛拟機(JVM)指定對象的類型并且運作該對象的方法。
是以在上面的例子中,之是以能編譯成功,是因為Animal類中存在move方法,然而運作時,運作的是特定對象的方法。
方法的重寫規則
- 父類的成員方法隻能被它的子類重寫。
- 聲明為final的方法不能被重寫。
- 聲明為static的方法不能被重寫,但是能夠被再次聲明。
- 參數清單必須完全與被重寫方法的相同;
- 通路權限不能比父類中被重寫的方法的通路權限更低。
- 子類和父類在同一個包中,那麼子類可以重寫父類除了聲明為private和final的所有方法。
- 子類和父類不在同一個包中,那麼子類隻能夠重寫父類的聲明為public和protected的非final方法。
- 如果不能繼承一個方法,則不能重寫這個方法。
當需要在子類中調用父類的被重寫方法時,要使用super關鍵字。
Super關鍵字的使用:
執行個體如下:
public class Animal{
public void move(){
System.out.println("動物可以移動");
}
}
public class Cat extends Animal{
public void move(){
super.move(); // 應用super類的方法
System.out.println("貓可以跑和走");
}
}
public class TestCat{
public static void main(String args[]){
Animal b = new Cat(); // Cat 對象
b.move(); //執行 Cat類的方法
}
}
運作結果如圖:
重載(Overload)
重載(overloading) 是在一個類裡面,方法名字相同,而參數不同。傳回類型可以相同也可以不同。
每個重載的方法(或者構造函數)都必須有一個獨一無二的參數類型清單。
最常用的地方就是構造器的重載。
重載規則:
- 被重載的方法必須改變參數清單(參數個數或類型不一樣);
- 被重載的方法可以改變傳回類型;
- 被重載的方法可以改變通路修飾符;
- 被重載的方法可以聲明新的或更廣的檢查異常;
- 方法能夠在同一個類中或者在一個子類中被重載。
- 無法以傳回值類型作為重載函數的區分标準。
執行個體如下:
public class Calc {
public int getSum(int num1,int num2){
System.out.println("int");
return num1+num2;
}
public double getSum(double num1,double num2){
System.out.println("double");
return num1+num2;
}
public double getSum(double num1,double num2,double num3){
return num1+num2+num3;
}
public static void main(String[] args) {
Calc calc=new Calc();
System.out.println(calc.getSum(67, 89));
System.out.println(calc.getSum(67, 89,78.4));
}
}
問:重載(Overload)和重寫(Override)的差別?
答:方法的重載和重寫都是實作多态的方式,差別在于前者實作的是編譯時的多态性,而後者實作的是運作時的多态性。重載發生在一個類中,同名的方法如果有不同的參數清單(參數類型不同、參數個數不同或者二者都不同)則視為重載;重寫發生在子類與父類之間,重寫要求子類被重寫方法與父類被重寫方法有相同的參數清單,有相容的傳回類型,比父類被重寫方法更好通路,不能比父類被重寫方法聲明更多的異常(裡氏代換原則)。重載對傳回類型沒有特殊的要求,不能根據傳回類型進行區分。