方法的用途
可提高程式碼的可讀性高且易於維護,加速開發及維護的速度,並可重複使用,並讓不同的物件相互溝通及分散執行工作。在其它語言中使用函數 (function) 這個名稱來稱呼,但在物件導向的語言中則使用方法 (method) 來稱呼。
目的
一長串的程式碼中常有某些部份的功能是一樣的,或者是長的差不多,這些都稱為重複 (duplication) 的程式碼。如下面藍色的部份一模一樣,同樣是在列印陣列。
public static void main(String[] args) { int[] a= {38,25,10,40,50,52,70,68,90}; for (int i=0;i<a.length;i++){ System.out.printf("%d ", a[i]); } System.out.println(); int[] b= {10,26,52,43,50}; for (int i=0;i<b.length;i++){ System.out.printf("%d ", b[i]); } System.out.println(); }
重複代碼是程式的忌諱,當某個地方要更改時,比如希望改成如下
System.out.printf("%d, ", d[i]);
也就是希望印出來多一個 “,” ,那麼此時除了上面那一部份要更改,下面的那一部份也要再更改一次。當程式碼愈來愈長,重複的地方分散相隔好幾百行,這下要足一尋找,比大海撈針還難。
方法宣告
方法就是為了取代重複的代碼,基本語法如下。
public static 返回值 方法名稱([參數1[, 參數2....]])
比如
public static void print(String s){ }
方法若無返回值,則為返回值需為 void,若 return_type 有指定,則程式碼一定要有 return 關鍵字。上述的代碼可以精簡成如下。
public static void main(String[] args) { int[] a= {38,25,10,40,50,52,70,68,90}; print(a); int[] b= {10,26,52,43,50}; print(b); } public static void print(int[] x){ for (int i=0;i<x.length;i++){ System.out.printf("%d ",x[i]); } System.out.println(); }
返回值
方法中如果有 return 表示有返回值,返回的型態必需跟方法宣告的型態一樣,而且返回值只能有一個。
如果沒有 return,則宣告方法的型態必需為 void。
變動的參數 — varargs
方法的參數數量可以不確定,但每個參數的型態都必需相同,這種變動的參數稱為 varargs(Variable arguments)。
public class Main {
public static void main(String[] args) {
int a=add(38,25,10,40,50,52,70,68,90);
System.out.println(a);
int b=add(10,26,52,43,50);
System.out.println(b);
}
public static int add(int... nums){
int sum=0;
for (int i :nums){
sum += i;
}
return sum;
}
}
請注意 nums 其實是一個陣列物件,而且呼叫者也可以不傳入任何參數,「…」稱為省略號,只能出現在方法的最後一個參數。
public static int add(int x, int... y){} //這是合法ok的
public static int add(int... x, int y){} //這是錯誤的
常用的方法
Math.random
Math.random 可產生隨機亂數,其值介於 0~1 之間。
Math.pow(底數, 指數)
Math.pow(2,10);
可計算 2^10 = 1024。
底下的方法可以隨更產生小寫的 a~z 字元。
Math.random()*26+97
Math所有方法皆為static,不需實例化Math類別即可呼叫裏面的方法,此種方法又稱為類別方法。
遞迴(Recursive)
在方法中自已呼叫自已稱為遞迴 (Recursive),但其實並不是自已呼叫自已,而是自已調用產生了一個跟自已一模一樣的全新方法。
public class Test { public static void main(String[] args) { int total=fac(5); System.out.printf("5*4*3*2*1= %d", total); } public static int fac(int x){ if(x==1)return 1; else return x*fac(x-1); } }
方法重載(OverLoading)
在主程式中,如果有底下的要求
int a=add(5, 10); float b=add(5.5f, 2);
呼叫 add 時,所傳入的參數型態不一樣,那要如何定義 add(?, ?) 呢? 為了解決上述的問題,Java 允許使用相同的方法名稱,這種相同的方法名稱叫作方法重載 (over loadding),如下所示。
public class Main { public static void main(String[] args) { int a=add(10,20); System.out.println(a); float b=add(10.5f, 20); System.out.println(b); } public static int add(int x, int y){ return x+y; } public static float add(float x, int y){ return x+y; } }
方法重載有一個條件限制,就是簽名不能一樣,方法名+參數型態+參數個數叫作簽名。簽名若一樣則不可重載。注意一點,方法的傳回值並不在簽名的範圍之內。比如
public int sum(int one, int two) public int sum(int one, int two, int three) : ok public float sum(float one, int two) : ok public int sum(int x, int y) : error public float sum(int one, int two) : error
底下是 OCP 常出的考古題
Which method corresponds to the following method call? pokemon.setInfo(2, 25.6f, "Pikachi"); A. public void setInfo(int level, float weight) B. public void setInfo(level, float weight, name) C. public void setInfo(float weight, String name, int level) D. public void setInfo(int level, float weight, String name) Answer : D