static void f3(short x) { prt("f3(short)"); } static void f3(int x) { prt("f3(int)"); } static void f3(long x) { prt("f3(long)"); } static void f3(float x) { prt("f3(float)"); } static void f3(double x) { prt("f3(double)");} static void prt(String s) { System.out.println(s); }
方法的重載(有的翻譯成過載)就是方法名相同,方法的參數序列不相同(這裡不是指繼承關係中的重寫):
1)僅僅是傳回型別不同,不能重載;這在一般程式設計語言中都是這樣規定的,原因非常簡單,根據傳回型別確定要調用那個方法,
需要根據傳回值的接受者類型來確定,這在很多時候都是非常困難的(例如接受類型是Object,或者不需要接收傳回值的情況)。
2)參數序列的不同主要是指參數類型序列的不同,而不是參數名字的不同;
3)在確定參數類型不同時,不會考慮繼承關係,雖然ClassA是ClassB的父類,下面:
public String DoSomething(ClassA A)和public String DoSomething(ClassB B)是符合重載的.
對於重載需要注意以下:
1)對於主類型(基本類型)重載,如果調用時實參是變數或者指定了類型的常數(2.0d),或者常數的類型唯一確定(字元,字串,布爾),
則根據變數類型來選擇要調用的方法,但對於實參是常數,不易確定的數字類型,在沒有明確類型標記的情況下,一般整數會轉換成int型,
一般小數會被轉換成double,測試如下:
//調用測試:
char a='A'; f3(a); f3(1); //f3(10000000000);出錯 f3(10000000000l); f3(2.0); f3(2.0f); f3(2.0d);
測試結果:
f3(int)
f3(int)
f3(long)
f3(double)
f3(float)
f3(double)
2)對於有繼承關係的類型形成的重載,調用的時候也是根據變數類型來確定調用方法的,只不過,如果當前變數類型沒有,則尋著父類型方向
向上尋找,直到找到為止(肯定會找到,如果找不到編譯的時候就會報錯):
下面的MyClassA->D依次為父子關係,下面是重載方法:
public class OverloadClass {public void DoSomething(MyClassA a){System.out.println("MyClassA a:"+a.getClass().getName());} public void DoSomething(MyClassB b) { System.out.println("MyClassB b:"+b.getClass().getName()); } public void DoSomething2(MyClassA a) { System.out.println("MyClassA a:"+a.getClass().getName()); } public void DoSomething2(MyClassC c) { System.out.println("MyClassC c:"+c.getClass().getName()); } public void DoSomething3(MyClassC c) { System.out.println("MyClassC c:"+c.getClass().getName()); }}
重載測試代碼:
OverloadClass theOC = new OverloadClass(); MyClassA theA = new MyClassA(); MyClassB theB = new MyClassB(); MyClassA theC = new MyClassC(); MyClassB theD = new MyClassC(); MyClassC theE = new MyClassD(); MyClassD theF = new MyClassD(); //theOC.DoSomething(theA); //theOC.DoSomething(theB); //theOC.DoSomething(theC); theOC.DoSomething2(theA); theOC.DoSomething2(theB); theOC.DoSomething2(theC); theOC.DoSomething2(theD); theOC.DoSomething2(theE); theOC.DoSomething2(theF); //theOC.DoSomething3(theA);//編譯錯誤.
這種重載判斷規則,同樣也適用於C#.之所以重載是根據變數類型而不是實際類型來判斷,其實原因非常簡單,因為重載是在編譯期就
會確定的,這個時候變數類型也是確定的,因此比較好判斷,而實際類型往往是在運行期間才知道,編譯期的重載當然不可能根據運行期
的事情來確定(這也是強型別語言的一個優勢和劣勢)。
PS:建構函式也可以重載。注意如果在建構函式中調用另外一個建構函式一定要放在建構函式的第1行,且只能調用一次。這個規定在C#中
也是一樣,只是書寫文法不一樣。