類別
class 語法跟現代 JavaScript 一樣,TypeScript 在上面加了型別註記與存取修飾詞,讓物件導向風格的程式碼更安全。
基本語法
class Animal {
name: string
private age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
speak(): string {
return `${this.name} makes a noise.`
}
}
const dog = new Animal("Rex", 3)
console.log(dog.speak())
屬性要先宣告型別(name: string),建構子裡再賦值;也可以像下面這樣用建構子參數簡寫,省掉重複宣告:
寫在建構子參數前面的存取修飾詞,會自動變成同名的屬性並完成賦值,效果跟上面完整寫法一樣。
存取修飾詞
| 修飾詞 | 誰能存取 |
|---|---|
public(預設,可省略) |
任何地方 |
private |
只有這個 class 內部 |
protected |
這個 class 與子類別內部 |
readonly |
只能在宣告或建構子裡賦值一次 |
class Account {
readonly id: string
private balance: number = 0
constructor(id: string) {
this.id = id
}
deposit(amount: number) {
this.balance += amount
}
}
const acc = new Account("A001")
acc.deposit(100)
// acc.balance = 500 // 編譯錯誤:balance 是 private
private/protected 是編譯期檢查,編譯成 JS 後這層保護就不存在;需要執行期也真正私有,可改用 JavaScript 原生的 # 私有欄位語法(#balance),TypeScript 一樣支援。
implements:讓 class 符合 interface
interface Speaker {
speak(): string
}
class Robot implements Speaker {
speak(): string {
return "Beep boop."
}
}
implements 強制這個 class 一定要有符合 Speaker 形狀的成員,常用來確保多個不同 class(例如不同的付款方式、不同的資料來源)遵守同一套介面。
繼承(extends)
class Cat extends Animal {
meow(): string {
return `${this.name} says meow!`
}
}
const cat = new Cat("Tom", 2)
console.log(cat.speak()) // 繼承自 Animal
console.log(cat.meow())
extends 用法跟一般 JavaScript class 相同;子類別會繼承父類別的屬性與方法,也能覆寫(override)父類別的方法。
相關影音
Traversy Media 這支涵蓋 class、存取修飾詞與 implements 的實際用法,也在 Interface 與 Type 提過;Net Ninja 播放清單 裡另有專講 Classes、Public/Private/Readonly、Interfaces with Classes 的分集,可依序往下看。