如果一個類中有多個具有相同名稱但參數(shù)不同的方法,則稱為方法重載。如果只需要執(zhí)行一個操作,具有相同的方法名稱將增加程序的可讀性。
假設(shè)必須執(zhí)行給定數(shù)值的添加操作(求和),但是參數(shù)的數(shù)量不固定,如果為兩個參數(shù)編寫add1(int,int)方法,為三個參數(shù)編寫add2(int,int,int)方法,可能對其他程序員來說很難理解這樣的方法的行為,因為它的名稱不同。
因此,執(zhí)行方法重載能比較容易理解程序含義。
方法重載的優(yōu)點
重載方法不同的方式
在java中重載方法有兩種方式,它們分別是:
注意:在java中,只通過更改方法的返回類型來實現(xiàn)方法重載是不可以的。
在這個例子中,我們將創(chuàng)建了兩個方法,第一個add()方法執(zhí)行兩個數(shù)值的相加操作,第二個add()方法執(zhí)行三個數(shù)值的相加操作。
在這個例子中,我們創(chuàng)建靜態(tài)方法,所以不需要創(chuàng)建實例來調(diào)用方法。
class Adder {
static int add(int a, int b) {
return a + b;
}
static int add(int a, int b, int c) {
return a + b + c;
}
}
class TestOverloading1 {
public static void main(String[] args) {
System.out.println(Adder.add(11, 11));
System.out.println(Adder.add(11, 11, 11));
}
}
上面代碼執(zhí)行后,輸出結(jié)果如下 -
22
33
在這個例子中,創(chuàng)建了兩種數(shù)據(jù)類型不同的方法。 第一個add方法接收兩個整數(shù)參數(shù),第二個add方法接收兩個雙精度型參數(shù)。
class Adder {
static int add(int a, int b) {
return a + b;
}
static double add(double a, double b) {
return a + b;
}
}
class TestOverloading2 {
public static void main(String[] args) {
System.out.println(Adder.add(11, 11));
System.out.println(Adder.add(12.3, 12.6));
}
}
上面代碼執(zhí)行后,輸出結(jié)果如下 -
22
24.9
問題:為什么方法重載不能通過更改方法的返回類型?
在java中,只通過改變方法的返回類型來實現(xiàn)方法重載是不可能的,因為這樣具有模糊性。 讓我們來看看模糊性是怎么樣發(fā)生的:
class Adder {
static int add(int a, int b) {
return a + b;
}
static double add(int a, int b) {
return a + b;
}
}
class TestOverloading3 {
public static void main(String[] args) {
System.out.println(Adder.add(11, 11));// ambiguity
}
}
上面代碼執(zhí)行后,輸出結(jié)果如下 -
Compile Time Error: method add(int,int) is already defined in class Adder
System.out.println(Adder.add(11,11));//這里,java如何確定應(yīng)該調(diào)用哪個sum()方法?
注意:編譯時錯誤優(yōu)于運行時錯誤。 所以,如果你聲明相同的方法具有相同的參數(shù),java編譯器渲染編譯器時間錯誤。
可以重載java main()方法嗎?
這是完全可以的。 可以通過方法重載在類中有任意數(shù)量的main方法。 但是JVM調(diào)用main()方法,它只接收字符串?dāng)?shù)組作為參數(shù)。 讓我們來看一個簡單的例子:
class TestOverloading4{
public static void main(String[] args){System.out.println("main with String[]");}
public static void main(String args){System.out.println("main with String");}
public static void main(){System.out.println("main without args");}
}
上面代碼執(zhí)行后,輸出結(jié)果如下 -
main with String[]
如果沒有找到匹配的數(shù)據(jù)類型,那么會隱式地將一個類型提升到另一個類型。 讓我們通過下面的圖示來理解這個概念:
如上圖所示,byte可以被提升為short,int,long,float或double。 short數(shù)據(jù)類型可以提升為int,long,float或double。 char數(shù)據(jù)類型可以提升為int,long,float或double等等。
使用類型提升方法重載的示例
class OverloadingCalculation1 {
void sum(int a, long b) {
System.out.println(a + b);
}
void sum(int a, int b, int c) {
System.out.println(a + b + c);
}
public static void main(String args[]) {
OverloadingCalculation1 obj = new OverloadingCalculation1();
obj.sum(20, 20);// now second int literal will be promoted to long
obj.sum(20, 20, 20);
}
}
上面代碼執(zhí)行后,輸出結(jié)果如下 -
40
60
如果找到匹配使用類型提升方法重載示例
如果方法中存在匹配類型參數(shù),則不會執(zhí)行類型提升方法重載。
class OverloadingCalculation2 {
void sum(int a, int b) {
System.out.println("int arg method invoked");
}
void sum(long a, long b) {
System.out.println("long arg method invoked");
}
public static void main(String args[]) {
OverloadingCalculation2 obj = new OverloadingCalculation2();
obj.sum(20, 20);// now int arg sum() method gets invoked
}
}
上面代碼執(zhí)行后,輸出結(jié)果如下 -
Output:int arg method invoked
在模糊的情況下使用類型提升來實現(xiàn)方法重載的示例
如果在方法中沒有匹配的類型參數(shù),并且每個方法都會提升相同數(shù)量的參數(shù),那么會出現(xiàn)歧義。如下示例代碼,將會產(chǎn)生編譯時錯誤。
class OverloadingCalculation3 {
void sum(int a, long b) {
System.out.println("a method invoked");
}
void sum(long a, int b) {
System.out.println("b method invoked");
}
public static void main(String args[]) {
OverloadingCalculation3 obj = new OverloadingCalculation3();
obj.sum(20, 20);// now ambiguity
}
}
注意: 只有一種類型不被隱式地去提升,例如
double不能被隱含地提升到任何類型。