昨天開始接觸 Java 的物件導向,學習了 Class 和 Object。
我們建立了 Expense 類別,讓「消費項目」和「消費金額」可以放在同一個物件裡。
昨天建立一筆消費時,需要這樣寫:
Expense expense = new Expense();
expense.item = "早餐";
expense.amount = 60;
雖然可以正常使用,但如果每建立一個物件都要一個一個設定資料,程式碼會有點麻煩。
所以今天要學習 Constructor(建構子),讓建立物件的同時就可以直接把資料放進去。
什麼是 Constructor?
Constructor 是建立 Object 時會執行的一段程式。
昨天的 Expense Class 是:
class Expense {
String item;
int amount;
}
今天可以加入 Constructor:
class Expense {
String item;
int amount;
Expense(String item, int amount) {
this.item = item;
this.amount = amount;
}
}
這樣建立物件時,就可以直接寫:
Expense expense = new Expense("早餐", 60);
一行就完成一筆消費資料。
Constructor 有什麼特色?
Constructor 有一個很重要的特色:
名稱必須和 Class 名稱相同。
我們的 Class 叫:
class Expense
所以 Constructor 也叫:
Expense(String item, int amount)
而且 Constructor 不需要寫 void。
例如這樣:
public void Expense()
就不是我們今天要使用的 Constructor。
this 是什麼?
今天還出現了一個新的關鍵字:
this
例如:
this.item = item;
this.amount = amount;
一開始看起來很像左右兩邊都一樣,其實代表的東西不同。
以這行為例:
this.item = item;
左邊:
this.item
代表「這個 Object 裡面的 item」。
右邊:
item
代表建立物件時傳進 Constructor 的資料。
例如:
new Expense("早餐", 60);
就可以想成:
item → 早餐
amount → 60
接著 Constructor 把這些資料存進 Object 裡。
昨天和今天的差別
昨天建立物件:
Expense expense = new Expense();
expense.item = "早餐";
expense.amount = 60;
今天:
Expense expense = new Expense("早餐", 60);
寫起來簡單很多,而且建立物件的時候就可以確保一筆消費同時具有項目和金額。
今天的小實作:加入 Constructor
今天繼續修改個人記帳系統:
import java.util.Scanner;
import java.util.ArrayList;
class Expense {
String item;
int amount;
Expense(String item, int amount) {
this.item = item;
this.amount = amount;
}
}
public class Main {
static Scanner scanner = new Scanner(System.in);
static ArrayList expenses = new ArrayList<>();
public static void main(String[] args) {
boolean running = true;
while (running) {
showMenu();
System.out.print("請選擇功能:");
int choice = scanner.nextInt();
scanner.nextLine();
switch (choice) {
case 1:
addExpense();
break;
case 2:
showExpenses();
break;
case 3:
running = false;
System.out.println("已離開個人記帳系統!");
break;
default:
System.out.println("輸入錯誤,請重新選擇!");
}
}
scanner.close();
}
public static void showMenu() {
System.out.println();
System.out.println("===== 個人記帳系統 =====");
System.out.println("1. 新增消費");
System.out.println("2. 查看紀錄");
System.out.println("3. 離開");
}
public static void addExpense() {
System.out.print("請輸入消費項目:");
String item = scanner.nextLine();
System.out.print("請輸入消費金額:");
int amount = scanner.nextInt();
scanner.nextLine();
Expense expense = new Expense(item, amount);
expenses.add(expense);
System.out.println("記帳成功!");
}
public static void showExpenses() {
System.out.println();
System.out.println("===== 消費紀錄 =====");
if (expenses.size() == 0) {
System.out.println("目前沒有消費紀錄。");
} else {
for (int i = 0; i < expenses.size(); i++) {
Expense expense = expenses.get(i);
System.out.println(
(i + 1) + ". "
+ expense.item + ":"
+ expense.amount + " 元"
);
}
}
}
}
今天真正修改了哪裡?
其實今天大部分的記帳系統都和昨天相同。
主要修改的是 Expense:
class Expense {
String item;
int amount;
Expense(String item, int amount) {
this.item = item;
this.amount = amount;
}
}
以及新增消費時:
Expense expense = new Expense(item, amount);
例如使用者輸入:
請輸入消費項目:午餐
請輸入消費金額:120
實際上就相當於:
new Expense("午餐", 120);
最後再:
expenses.add(expense);
把這個物件加入 ArrayList。
執行結果
新增第一筆:
===== 個人記帳系統 =====
再新增:
請輸入消費項目:午餐
請輸入消費金額:120
記帳成功!
查看紀錄:
===== 消費紀錄 =====
畫面和昨天沒有太大差別,但程式內部建立物件的方法變得更簡潔。
再增加一個「分類」
既然已經有 Constructor,今天也試著讓一筆消費保存更多資料。
加入:
String category;
Expense 就可以改成:
class Expense {
String item;
int amount;
String category;
Expense(String item, int amount, String category) {
this.item = item;
this.amount = amount;
this.category = category;
}
}
建立物件時:
Expense expense =
new Expense("午餐", 120, "飲食");
這個 Object 裡就會包含:
項目:午餐
金額:120
分類:飲食
這也讓我開始理解使用 Class 的好處。
之後如果還要增加日期、付款方式等資訊,都可以繼續放進 Expense 裡,而不是建立很多互相分開的 ArrayList。
Day 12 學習心得
今天學習了 Java 的 Constructor 建構子,也更進一步理解昨天學到的 Class 和 Object。
昨天建立物件之後還需要一個一個設定資料,今天使用 Constructor 之後,可以在建立 Object 的同時直接傳入消費項目和金額,程式碼變得比較簡潔。
今天一開始比較容易搞混的是 this.item = item,後來理解左邊代表物件本身的變數,右邊則是傳進 Constructor 的資料後,就比較清楚了。
目前每一筆消費已經可以整理成一個 Expense Object。接下來如果再把物件裡的資料保護起來,應該就會更接近完整的物件導向寫法。