視使用情境或條件的不同,建構物件時也許希望有對應的初始流程,你可以定義多個建構式,只要參數型態或個數不同,這稱之為重載(Overload)建構式。例如:
public class Some {
private int a = 10;
private String text = "n.a.";
public Some(int a) {
if(a > 0) {
this.a = a;
}
}
public Some(int a, String text) {
if(a > 0) {
this.a = a;
}
if(text != null) {
this.text = text;
}
}
...
}
在這個程式碼片段中,建構時有兩種選擇,一是使用new Some(100)
的方式,另一個是使用new Some(100, "some text")
的方式。
有些場合建議,如果定義了有參數的建構式,也可以加入無參數建構式,即使內容為空也無所謂,這是為了日後使用上的彈性,例如運用反射(Reflection)機制生成物件的需求,或者是繼承時呼叫父類別建構式時的方便。
定義方法時也可以進行重載,可為類似功能的方法提供統一名稱,但根據參數型態或個數的不同呼叫對應的方法。以String
類別為例,其valueOf()
方法就提供了多個版本:
public static String valueOf(boolean b)
public static String valueOf(char c)
public static String valueOf(char[] data)
public static String valueOf(char[] data, int offset, int count)
public static String valueOf(double d)
public static String valueOf(float f)
public static String valueOf(int i)
public static String valueOf(long l)
public static String valueOf(Object obj)
雖然呼叫的方法名稱都是valueOf()
,但根據傳遞的引數型態不同,會呼叫對應的方法,例如呼叫String.valueOf(10)
,因為10是int
型態,所以會執行valueOf(int i)
的版本,若是String.valueOf(10.12)
,因為10.12是double
型態,會執行valueOf(double d)
的版本(片段中看到的static
之後就會說明)。
方法重載讓程式設計人員不用苦惱方法名稱的設計,可用一致的名稱來呼叫類似功能的方法,方法重載可根據傳遞引數的型態不同,也可根據參數列個數的不同來設計方法重載。例如:
public class SomeClass {
public void someMethod() {
}
public void someMethod(int i) {
}
public void someMethod(float f) {
}
public void someMethod(int i, float f) {
}
}
返回值型態不可作為方法重載依據,例如以下方法重載並不正確,編譯器會將兩個someMethod()
視為重複定義而編譯失敗:
public class Some {
public int someMethod(int i) {
return 0;
}
public double someMethod(int i) {
return 0.0;
}
}
在JDK5之後使用方法重載時,要注意自動裝箱、拆箱問題,來看看以下程式的結果會是什麼?
package cc.openhome;
class Some {
void someMethod(int i) {
System.out.println("int 版本被呼叫");
}
void someMethod(Integer integer) {
System.out.println("Integer 版本被呼叫");
}
}
public class OverloadBoxing {
public static void main(String[] args) {
Some s = new Some();
s.someMethod(1);
}
}
結果是顯示「int
版本被呼叫」,如果想呼叫參數為Integer
版本的方法,要明確指定。例如:
s.someMethod(new Integer(1));
編譯器在處理重載方法時,會依以下順序來處理:
- 還沒有裝箱動作前可符合引數個數與型態的方法
- 裝箱動作後可符合引數個數與型態的方法
- 嘗試有不定長度引數並可符合引數型態的方法
- 找不到合適的方法,回報編譯錯誤