在Java 中,同一個類中的2個或2個以上的方法可以有同一個名字,只要它們的參數聲明不同即可。在這種情況下,該方法就被稱為重載(overloaded ),這個過程稱為方法重載(method overloading )。方法重載是Java 實現多態性的一種方式。如果你以前從來沒有使用過一種允許方法重載的語言,這個概念最初可能有點奇怪。但是你將看到,方法重載是Java 最激動人心和最有用的特性之一。 當一個重載方法被調用時,Java 用參數的類型和(或)數量來表明實際調用的重載方法的版本。因此,每個重載方法的參數的類型和(或)數量必須是不同的。雖然每個重載方法可以有不同的傳回型別,但傳回型別並不足以區分所使用的是哪個方法。當Java 調用一個重載方法時,參數與調用參數匹配的方法被執行。 下面是一個說明方法重載的簡單例子: // Demonstrate method overloading. class OverloadDemo { void test() { System.out.println("No parameters"); } // Overload test for one integer parameter. void test(int a) { System.out.println("a: " + a); } // Overload test for two integer parameters. void test(int a,int b) { System.out.println("a and b: " + a + " " + b);} // overload test for a double parameter double test(double a) { System.out.println("double a: " + a); return a*a; }} class Overload { public static void main(String args[]) { OverloadDemo ob = new OverloadDemo(); double result; // call all versions of test()ob.test();ob.test(10);ob.test(10,20);result = ob.test(123.25);
System.out.println("Result of ob.test(123.25): " + result); } } 該程式產生如下輸出: No parameters a: 10 a and b: 10 20 double a: 123.25 Result of ob.test(123.25): 15190.5625 從上述程式可見,test()被重載了四次。第一個版本沒有參數,第二個版本有一個整型參數,第三個版本有兩個整型參數,第四個版本有一個double 型參數。由於重載不受方法的傳回型別的影響,test()第四個版本也返回了一個和重載沒有因果關係的值。 當一個重載的方法被調用時,Java 在調用方法的參數和方法的自變數之間尋找匹配。但是,這種匹配並不總是精確的。在一些情況下,Java 的自動類型轉換也適用於重載方法的自變數。例如,看下面的程式: // Automatic type conversions apply to overloading. class OverloadDemo { void test() { System.out.println("No parameters"); } // Overload test for two integer parameters. void test(int a,int b) { System.out.println("a and b: " + a + " " + b);} // overload test for a double parameter void test(double a) { System.out.println("Inside test(double) a: " + a); } } class Overload { public static void main(String args[]) { OverloadDemo ob = new OverloadDemo(); int i = 88; ob.test();ob.test(10,20); ob.test(i); // this will invoke test(double) ob.test(123.2); // this will invoke test(double) } } 該程式產生如下輸出: No parameters a and b: 10 20 Inside test(double) a: 88 Inside test(double) a: 123.2 在本例中,OverloadDemo 的這個版本沒有定義test(int) 。因此當在Overload 內帶整數參數調用test()時,找不到和它匹配的方法。但是,Java 可以自動地將整數轉換為double 型,這種轉換就可以解決這個問題。因此,在test(int) 找不到以後,Java 將i擴大到double 型,然後調用test(double) 。當然,如果定義了test(int) ,當然先調用test(int) 而不會調用test(double) 。只有在找不到精確匹配時,Java 的自動轉換才會起作用。 方法重載支援多態性,因為它是Java 實現“一個介面,多個方法”範型的一種方式。要理解這一點,考慮下面這段話:在不支援方法重載的語言中,每個方法必須有一個惟一的名字。但是,你經常希望實現資料類型不同但本質上相同的方法。可以參考絕對值函數的例子。在不支援重載的語言中,通常會含有這個函數的三個及三個以上的版本,每個版本都有一個差別甚微的名字。例如,在C語言中,函數abs( )返回整數的絕對值,labs( ) 返回long 型整數的絕對值( ),而fabs( )返回浮點值的絕對值。儘管這三個函數的功能實質上是一樣的,但是因為C語言不支援重載,每個函數都要有它自己的名字。這樣就使得概念情況複雜許多。儘管每一個函數潛在的概念是相同的,你仍然不得不記住這三個名字。在Java 中就不會發生這種情況,因為所有的絕對值函數可以使用同一個名字。確實,Java 的標準的類庫包含一個絕對值方法,叫做abs ( )。這個方法被Java 的math 類重載,用於處理數字類型。Java 根據參數類型決定調用的abs()的版本。 重載的價值在於它允許相關的方法可以使用同一個名字來訪問。因此,abs這個名字代表了它執行的通用動作(general action )。為特定環境選擇正確的指定(specific )版本是編譯器要做的事情。作為程式員的你,只需要記住執行的通用操作就行了。通過多態性的應用,幾個名字減少為一個。儘管這個例子相當簡單,但如果你將這個概念擴充一下,你就會理解重載能夠協助你解決更複雜的問題。 當你重載一個方法時,該方法的每個版本都能夠執行你想要的任何動作。沒有什麼規定要求重載方法之間必須互相關聯。但是,從風格上來說,方法重載還是暗示了一種關係。這就是當你能夠使用同一個名字重載無關的方法時,你不應該這麼做。例如,你可以使用sqr這個名字來建立一種方法,該方法返回一個整數的平方和一個浮點數值的平方根。但是這兩種操作在功能上是不同的。按照這種方式應用方法就違背了它的初衷。在實際的編程中,你應該只重載相互之間關係緊密的操作。 7.1.1 建構函式重載除了重載正常的方法外,建構函式也能夠重載。實際上,對於大多數你建立的現實的 類,重載建構函式是很常見的,並不是什麼例外。為了理解為什麼會這樣,讓我們回想上一章中舉過的Box類例子。下面是最新版本的Box類的例子: class Box { double width; double height; double depth; // This is the constructor for Box. Box(double w,double h,double d) {width = w; height = h;depth = d; } // compute and return volume double volume() { return width * height * depth;}}