Skip to main content

Class

類別(Class)就像一個設計圖,能透過它產生一個新物件,class 中會定義屬性和方法

class Car {
description: string;

constructor() {
this.description = "This is car";
}

public getDescription(): string {
return this.description;
}
}

const car1 = new Car();

// print 出 "This is car"
console.log(car1.getDescription());

建構函式 constructor

建構函式會在創建 instance 時自動調用,用於初始化物件的屬性。

class Contact {
// STEP 1 - 定義這個 class 中有的 fields,及其 modifiers(預設是 public)
// STEP 2 - 給予 fields 初始值
email: string = "kira@gmail.com";
// public 可以不要寫(預設是 public)
public name: string = "Kira";
protected idNumber: string = "B00000";
private passwordSeed: number = 1;

// STEP 3: 如果需要從外部帶入參數,可以在 constructor 中取得
constructor(idNumber: string, name: string, email: string = "no email") {
this.idNumber = idNumber;
this.name = name;

// 如果沒寫這行,則會直接用 initializers 中的值("kira@gmail.com")
// 而不是 constructor 中的 defaultValue("no-email")
this.email = email;
}
}

const c = new Contact("A123456789", "Peter");
console.log(c.email); // "no email"

對於會在 constructor 中出現的 fields,可以不用在上方先定義其 fields。因此,上面程式碼可以寫成:

class Contact {
private passwordSeed: number = 1;

// 對於會在 constructor 中出現的 fields,可以不用在上方先定義其 fields
constructor(
protected idNumber: string = "B00000",
public name: string = "Kira",
public email: string = "no email"
) {
// TS 會自己執行 this.xxx = xxx 的程式,因此我們不需要在做些什麼
}
}

const c = new Contact();
console.log(c.email); // "no email"

如果省略 define fields 的步驟,直接在 constructor 中帶入時,如果是 public 的 fields 也要明確定義

訪問修飾符 Public, Private 和 Protected

  • Public: 可以從 class 內部和外部存取(沒有設定則預設為 public)
  • Protected: 僅能從 class 內部和子類(繼承父層 class)存取,外部無法存取
class Animal {
protected name: string;

constructor(name: string) {
this.name = name;
}
}

class Cat extends Animal {
meow() {
console.log(`${this.name} says meow`); // 可以在子類存取 protected 屬性
}
}

const myCat = new Cat("Whiskers");
console.log(myCat.name); // 會出現錯誤,外部不能存取 protected 屬性
  • Private:僅能從 class 內部存取,外部不能存取,通常用於避免外部直接讀取和修改
class BankAccount {
private balance: number;

constructor(initialBalance: number) {
this.balance = initialBalance;
}

getBalance() {
return this.balance; // 可以在class內部存取 balance
}
}

const myAccount = new BankAccount(1000);
console.log(myAccount.balance); // 會出現錯誤,外部無法取得 private 屬性

ECMAScript 2022 後可以使用# (JS 也可使用) 来實踐同樣的 private 效果

Static 關鍵字

倘若不希望創建 instance 就可以操作 class 的的屬性或方法,便可使用 static 關鍵字

class Calculator {
static add(x: number, y: number): number {
return x + y;
}
}

const result = Calculator.add(5, 3); // 可以直接使用class method,不需要創建 instance

super ()

super() 用於調用父類的 constructor,主要作用是在子類的 constructor 中執行從父類繼承的 constructor,並進行必要的初始化。

class Animal {
constructor(name: string) {
this.name = name;
}

makeSound() {
console.log("Animal makes a sound");
}
}

class Dog extends Animal {
constructor(name: string, breed: string) {
super(name); // 調用父類的constructor,傳遞name參數
this.breed = breed;
}

makeSound() {
console.log("Dog barks");
}

introduce() {
console.log(`I'm a ${this.breed} dog named ${this.name}`);
}
}

const myDog = new Dog("Buddy", "Golden Retriever");
myDog.makeSound(); // 調用子類的方法

參考資料