TypeScript 抽象類別 (Abstract Class)
所有的房子都是「建築物」,但世界上不存在一棟建築物就叫「建築物」。它一定會有更具體的型態,像是「公寓」、「透天」或「摩天大樓」。
在程式設計中,抽象類別就是那個概念上的「建築物」。
什麼是抽象類別?
抽象類別像是一張未完成的藍圖。
- 不能被實例化:你不能
new 建築物(),因為它太抽象了。 - 作為基底:它可以被繼承。
- 包含抽象方法:它可以規定子類別「必須」實作哪些功能。
abstract class Animal {
// 1. 一般方法:子類別可以直接繼承使用,不用重寫
eat() {
console.log('Nom nom nom...');
}
// 2. 抽象方法:沒有內容,子類別「必須」實作
abstract makeSound(): void;
}
// const a = new Animal(); // 錯誤!抽象類別不能 new
實作抽象類別
當你繼承一個抽象類別時,你就像是簽了一份合約,承諾要把那些「未完成」的部分做完。
class Dog extends Animal {
// 必須實作 makeSound,否則編譯器會報錯
makeSound() {
console.log('汪汪!');
}
}
class Cat extends Animal {
makeSound() {
console.log('喵喵~');
}
}
const dog = new Dog();
dog.eat(); // 繼承自 Animal
dog.makeSound(); // 自己的實作
抽象類別 vs 介面 (Interface)
這是面試必考題,也是新手最容易搞混的。
| 特性 | 抽象類別 (Abstract Class) | 介面 (Interface) |
|---|---|---|
| 本質 | 是一個 Class,編譯後會有 JS 程式碼 | 只是型別定義,編譯後完全消失 |
| 實作 | 可以包含實作細節 (如 eat 方法) | 只能定義「形狀」,不能有程式碼 |
| 用途 | Code Reuse (程式碼共用):父類別幫你寫好一半,你寫剩下一半 | Contract (契約):規定你一定要有哪些屬性或方法 |
什麼時候用哪個?
- 如果你有多個類別有重複的邏輯 (例如大家都要
eat),用抽象類別。 - 如果你只是想規定一個標準規格 (例如大家都要有
print()方法,但實作方式完全不同),用介面。