iT邦幫忙

2026 iThome 鐵人賽

DAY 10
0
自我挑戰組

Java 程式設計與實作:30 天打造個人記帳系統系列 第 14 篇

Inheritance 繼承:建立不同類型的消費紀錄

  • 分享至 

  • xImage
  •  

昨天學習了 Java 物件導向中的 Encapsulation(封裝),利用 private、Getter 和 Setter 保護消費資料。

今天繼續學習另一個物件導向的重要觀念:Inheritance(繼承)。

目前所有消費都是使用同一個 Expense 類別,但實際記帳時會有很多不同類型,例如飲食、交通、購物等。這些消費都有共同的「項目」和「金額」,但不同類型也可能有自己的資料。

這時候就可以使用「繼承」。

什麼是 Inheritance?

Inheritance 可以讓一個新的 Class 使用另一個 Class 已經擁有的內容。

例如我們原本有:

class Expense {
private String item;
private int amount;
}

現在想建立一個專門記錄飲食的類別:

class FoodExpense extends Expense {
}

這裡最重要的是:

extends Expense

意思就是 FoodExpense 繼承 Expense。

可以簡單理解成:

Expense
│
├── FoodExpense
│
└── TransportationExpense

Expense 是比較一般的消費,而下面可以再建立不同種類的消費。

父類別和子類別

今天還會遇到兩個新的名稱:

Expense 稱為 父類別(Superclass)。

FoodExpense 稱為 子類別(Subclass)。

例如:

class FoodExpense extends Expense {
}

可以理解成:

FoodExpense 是一種 Expense。

飲食消費本來就是消費的一種,所以可以使用 Expense 原本就有的項目和金額。

建立 Expense 父類別

先建立我們原本的 Expense:

class Expense {
private String item;
private int amount;
Expense(String item, int amount) {
this.item = item;
this.amount = amount;
}
public String getItem() {
return item;
}
public int getAmount() {
return amount;
}
}

這裡保存所有消費都會有的:

item
amount

建立 FoodExpense

接著建立飲食消費:

class FoodExpense extends Expense {
private String mealType;
FoodExpense(String item, int amount, String mealType) {
super(item, amount);
this.mealType = mealType;
}
public String getMealType() {
return mealType;
}
}

這次多了一個:

private String mealType;

用來記錄:

早餐
午餐
晚餐

所以一筆 FoodExpense 可以包含:

項目:牛肉麵
金額:150
餐別:午餐

super 是什麼?

今天另外出現:

super(item, amount);

super 可以用來呼叫父類別的 Constructor。

例如:

FoodExpense food =
new FoodExpense("牛肉麵", 150, "午餐");

其中:

牛肉麵
150

會透過:

super(item, amount);

交給 Expense。

而:

午餐

則由 FoodExpense 自己保存。

可以簡單想成:

FoodExpense
│
├── Expense 負責
│ ├── 牛肉麵
│ └── 150 元
│
└── FoodExpense 自己負責
└── 午餐

再建立 TransportationExpense

除了飲食,也可以建立交通消費:

class TransportationExpense extends Expense {
private String transportType;
TransportationExpense(
String item,
int amount,
String transportType
) {
super(item, amount);
this.transportType = transportType;
}
public String getTransportType() {
return transportType;
}
}

例如:

TransportationExpense transport =
new TransportationExpense("上學", 30, "捷運");

就代表:

項目:上學
金額:30 元
交通方式:捷運

今天的小實作

今天先做一個簡單版本,看看繼承實際使用起來是什麼樣子。

class Expense {
private String item;
private int amount;
Expense(String item, int amount) {
this.item = item;
this.amount = amount;
}
public String getItem() {
return item;
}
public int getAmount() {
return amount;
}
}
class FoodExpense extends Expense {
private String mealType;
FoodExpense(String item, int amount, String mealType) {
super(item, amount);
this.mealType = mealType;
}
public String getMealType() {
return mealType;
}
}
class TransportationExpense extends Expense {
private String transportType;
TransportationExpense(
String item,
int amount,
String transportType
) {
super(item, amount);
this.transportType = transportType;
}
public String getTransportType() {
return transportType;
}
}
public class Main {
public static void main(String[] args) {
FoodExpense food =
new FoodExpense("牛肉麵", 150, "午餐");
TransportationExpense transport =
new TransportationExpense("上學", 30, "捷運");
System.out.println("===== 飲食消費 =====");
System.out.println("項目:" + food.getItem());
System.out.println("金額:" + food.getAmount() + " 元");
System.out.println("餐別:" + food.getMealType());
System.out.println();
System.out.println("===== 交通消費 =====");
System.out.println("項目:" + transport.getItem());
System.out.println("金額:" + transport.getAmount() + " 元");
System.out.println(
"交通方式:" + transport.getTransportType()
);
}
}

執行結果

===== 飲食消費 =====
項目:牛肉麵
金額:150 元
餐別:午餐
===== 交通消費 =====
項目:上學
金額:30 元
交通方式:捷運

雖然 FoodExpense 裡面沒有重新寫:

getItem()
getAmount()

但是因為它:

extends Expense

所以可以直接使用從 Expense 繼承下來的方法。

這就是繼承很方便的地方。

為什麼不全部寫在同一個 Class?

如果不用繼承,我可能要分別寫:

FoodExpense
→ item
→ amount
→ mealType
TransportationExpense
→ item
→ amount
→ transportType

這樣 item 和 amount 就一直重複。

使用繼承之後,可以把共同內容放在:

Expense
→ item
→ amount

不同類型再增加自己的內容:

FoodExpense
→ mealType
TransportationExpense
→ transportType

這樣程式的結構會比較清楚,也可以減少重複的程式碼。

今天怎麼記 Inheritance?

我覺得今天最重要的是先記住:

extends

就是「繼承」。

例如:

class FoodExpense extends Expense

可以直接理解成:

FoodExpense 是 Expense 的一種。

而:

super(item, amount);

則是把資料交給父類別的 Constructor 處理。

所以今天可以先記成:

Expense(父類別)
↓ extends
FoodExpense(子類別)
super()
↓
呼叫父類別的 Constructor

Day 14 學習心得

今天學習了 Java 物件導向中的 Inheritance 繼承。剛開始看到父類別、子類別、extends 和 super 覺得有點複雜,但把它套用在記帳系統之後就比較容易理解。

不同類型的消費其實都有共同的項目和金額,所以可以先放在 Expense 裡,再讓飲食或交通消費繼承它,增加自己需要的資料。

我覺得繼承最大的好處是可以減少重複的程式碼,也讓不同類別之間的關係比較清楚。到今天為止,已經連續學習了 Class、Object、Constructor、Encapsulation 和 Inheritance,對 Java 的物件導向也比一開始更有概念。


上一篇
Encapsulation 封裝:保護記帳資料
下一篇
Exception Handling 例外處理:避免輸入錯誤讓程式當掉
系列文
Java 程式設計與實作:30 天打造個人記帳系統 共 19 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言