假設現在你的朋友使用CashCard
建立3個物件,並要再對所有物件進行儲值的動作:
Scanner scanner = new Scanner(System.in);
CashCard card1 = new CashCard("A001", 500, 0);
int money = scanner.nextInt();
if(money > 0) {
card1.balance += money;
if(money >= 1000) {
card1.bonus++;
}
}
else {
System.out.println("儲值是負的?你是來亂的嗎?");
}
CashCard card2 = new CashCard("A002", 300, 0);
money = scanner.nextInt();
if(money > 0) {
card2.balance += money;
if(money >= 1000) {
card2.bonus++;
}
}
else {
System.out.println("儲值是負的?你是來亂的嗎?");
}
CashCard card3 = new CashCard("A003", 1000, 1);
// 還是那些if..else的重複流程
...
你的朋友作了簡單的檢查,就是儲值不能是負的,而儲值大於1000的話,就給予紅利一點,很容易就可以發現,那些儲值的流程重複了。你想了一下,儲值這個動作應該是CashCard
物件自己處理!在Java中,你可以定義方法(Method)來解決這個問題:
package cc.openhome;
class CashCard {
String number;
int balance;
int bonus;
CashCard(String number, int balance, int bonus) {
this.number = number;
this.balance = balance;
this.bonus = bonus;
}
void store(int money) { // 儲值時呼叫的方法
if(money > 0) {
this.balance += money;
if(money >= 1000) {
this.bonus++;
}
}
else {
System.out.println("儲值是負的?你是來亂的嗎?");
}
}
void charge(int money) { // 扣款時呼叫的方法
if(money > 0) {
if(money <= this.balance) {
this.balance -= money;
}
else {
System.out.println("錢不夠啦!");
}
}
else {
System.out.println("扣負數?這不是叫我儲值嗎?");
}
}
int exchange(int bonus) { // 兌換紅利點數時呼叫的方法
if(bonus > 0) {
this.bonus -= bonus;
}
return this.bonus;
}
}
在CashCard
類別中,除了定義儲值用的store()
方法之外,你還考慮到扣款用的charge()
方法,以及兌換紅利點數的exchange()
方法。在類別中定義方法,如果不用傳回值,方法名稱前可以宣告void
。
先前看到的儲值重複流程,現在都封裝到store()
方法中,這麼作的好處是使用CashCard
的使用者,現在可以這麼撰寫了:
Scanner scanner = new Scanner(System.in);
CashCard card1 = new CashCard("A001", 500, 0);
card1.store(scanner.nextInt());
CashCard card2 = new CashCard("A002", 300, 0);
card2.store(scanner.nextInt());
CashCard card3 = new CashCard("A003", 1000, 1);
card3.store(scanner.nextInt());
好處是什麼顯而易見,相較於先前得撰寫重複流程,CashCard
使用者應該會比較想寫這個吧!你封裝了什麼呢?你封裝了儲值的流程。哪天你也許考慮每加值1000元就增加一點紅利,而不像現在就算加值5000元也只有一點紅利,就算改變了store()
的流程,CashCard
使用者也無需修改程式。
同樣地,charge()
與exchange()
方法也分別封裝了扣款以及兌換紅利點數的流程。為了知道兌換紅利點數後,剩餘的點數還有多少,exchange()
必須傳回剩餘的點數值,方法若會傳回值,必須於方法前宣告傳回值的型態。
在Java命名慣例中,方法名稱首字是小寫。
其實如果是直接建立三個CashCard
物件,而後進行儲值並顯示明細,可以如下使用陣列,讓程式更簡潔:
package cc.openhome;
import java.util.Scanner;
public class CardApp {
public static void main(String[] args) {
CashCard[] cards = {
new CashCard("A001", 500, 0),
new CashCard("A002", 300, 0),
new CashCard("A003", 1000, 1)
};
Scanner scanner = new Scanner(System.in);
for(CashCard card : cards) {
System.out.printf("為 (%s, %d, %d) 儲值:",
card.number, card.balance, card.bonus);
card.store(scanner.nextInt());
System.out.printf("明細 (%s, %d, %d)%n",
card.number, card.balance, card.bonus);
}
}
}
執行結果如下所示:
明細 (A001, 1500, 1)
為 (A002, 300, 0) 儲值:2000
明細 (A002, 2300, 1)
為 (A003, 1000, 1) 儲值:3000
明細 (A003, 4000, 2)