JAVA 方法過載(轉)

ba發表於2007-08-15
JAVA 方法過載(轉)[@more@]在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;}}

在本例中,Box() 建構函式需要三個自變數,這意味著定義的所有Box物件必須給Box() 建構函式傳遞三個引數。例如,下面的語句在當前情況下是無效的:

Box ob = new Box();

因為Box( )要求有三個引數,因此如果不帶引數的呼叫它則是一個錯誤。這會引起一些重要的問題。如果你只想要一個盒子而不在乎 (或知道)它的原始的尺寸該怎麼辦?或,如果你想用僅僅一個值來初始化一個立方體,而該值可以被用作它的所有的三個尺寸又該怎麼辦?如果Box 類是像現在這樣寫的,與此類似的其他問題你都沒有辦法解決,因為你只能帶三個引數而沒有別的選擇權。

幸好,解決這些問題的方案是相當容易的:過載Box 建構函式,使它能處理剛才描述的情況。下面程式是Box 的一個改進版本,它就是運用對Box建構函式的過載來解決這些問題的:

/* Here,Box defines three constructors to initialize

the dimensions of a box various ways.
*/
class Box {

double width; double height; double depth; // constructor used when all dimensions specified Box(double w,double h,double d) {

width = w;
height = h;
depth = d;

}

// constructor used when no dimensions specified Box() { width = -1; // use -1 to indicate
height = -1; // an uninitialized
depth = -1; // box
}

// constructor used when cube is created Box(double len) { width = height = depth = len;}

// compute and return volume double volume() { return width * height * depth;}}

class OverloadCons {

public static void main(String args[]) { // create boxes using the various constructorsBox mybox1 = new Box(10,20,15);Box mybox2 = new Box();Box mycube = new Box(7);

double vol;

// get volume of first box
vol = mybox1.volume();
System.out.println("Volume of mybox1 is " + vol);

// get volume of second box
vol = mybox2.volume();
System.out.println("Volume of mybox2 is " + vol);
// get volume of cube
vol = mycube.volume();
System.out.println("Volume of mycube is " + vol);

}
}

該程式產生的輸出如下所示:

Volume of mybox1 is 3000.0
Volume of mybox2 is -1.0
Volume of mycube is 343.0

在本例中,當new執行時,根據指定的自變數呼叫適當的建構函式。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617731/viewspace-958022/,如需轉載,請註明出處,否則將追究法律責任。

相關文章