建議6:覆寫變長方法也循規(guī)蹈矩
覆寫必須滿足的條件:
- 重寫方法不能縮小訪問權(quán)限。
- 參數(shù)列表必須與重寫方法相同。
- 返回類型必須與重寫方法的相同或是其子類。
- 重寫方法不能拋出新的異常,或者是超出父類范圍的異常,但是可以拋出更少、更有限的異常,或者不拋出異常。
參數(shù)列表相同包括:參數(shù)數(shù)量相同,類型相同,順序相同。
看下面代碼:
public class Client {
public static void main(String[] args) {
//向上轉(zhuǎn)型
Base base = new Sub();
base.fun(100, 50);
//不轉(zhuǎn)型
Sub sub = new Sub();
sub.fun(100, 50);
}
}
//基類
class Base{
void fun(int price,int... discounts){
System.out.println("Base......fun");
}
}
//子類,覆寫父類方法
class Sub extends Base{
@Override
void fun(int price,int[] discounts){
System.out.println("Sub......fun");
}
}
編譯不通過。
首先覆寫是正確的, 因為父類的fun編譯成字節(jié)碼后的形參是一個int類型的形參加上一個int數(shù)組類型的形參,子類的參數(shù)列表也與此相同,所以覆寫是正確的。
是sub.fun(100, 50)這條語句報錯,提示找不到fun(int,int)方法。
原因是:base對象是把子類對象Sub做了向上轉(zhuǎn)型,形參列表是由父類決定的,由于是變長參數(shù),在編譯時,“base.fun(100, 50)”中的“50”這個實參會被編譯器“猜測”而編譯成“{50}”數(shù)組,再由子類Sub執(zhí)行。我們再來看看直接調(diào)用子類的情況,這時編譯器并不會把“50”做類型轉(zhuǎn)換,因為數(shù)組本身也是一個對象,編譯器還沒有聰明到要在兩個沒有繼承關(guān)系的類之間做轉(zhuǎn)換,要知道Java是要求嚴(yán)格的類型匹配的,類型不匹配編譯器自然就會拒絕執(zhí)行,并給予錯誤提示。
注意:覆寫的方法參數(shù)與父類相同,不僅僅是類型,數(shù)量,還包括顯示形式