TypeScript - 抽象類別

你好,有抱負的程式設計師們!今天,我們將踏上一段令人興奮的旅程,探索TypeScript世界的強大功能之一:抽象類別。如果你是程式設計的新手,別擔心;我會一步步引導你理解這個概念,就像我過去幾年來為無數學生做的那樣。那麼,我們來深入了解一下吧!

TypeScript - Abstract Classes

抽象類別是什麼?

在我們深入探討抽象類別的細節之前,讓我們先用一個簡單的比喻來說明。想像你在一個汽車經銷商那裡,看到一個標誌上寫著「交通工具」。現在,你實際上不能購買一個「交通工具」,因為這太過籠統。你需要選擇一種特定的交通工具,比如汽車、卡車或摩托車。在程式設計中,抽象類別就像那個一般的「交通工具」概念一樣 - 它是其他類別的藍圖,但你不能直接從它創建一個物件。

TypeScript中的抽象類別作為其他類別可以繼承的基類。它們可能包含抽象方法(沒有實現的方法)和具體方法(有實現的方法)。要記住的一個關鍵點是,你不能直接創建一個抽象類別的實例。

創建抽象類別

現在,讓我們來看看如何在TypeScript中創建一個抽象類別。我們在class關鍵字之前使用abstract關鍵字。這裡有一個基本的結構:

abstract class 類名 {
// 屬性和方法放在這裡
}

抽象方法

抽象類別可以有抽象方法。這些方法是聲明的,但在抽象類別中沒有實現。任何繼承此抽象類的類必須為這些方法提供實現。

具體方法

抽象類別也可以有具體方法,這些是完整實現的方法,可以被子類繼承。

範例 1:Shape 抽象類別

讓我們創建一個簡單的範例來說明抽象類別是如何工作的。我們將創建一個抽象的Shape類別,並帶有一個抽象方法calculateArea()

abstract class Shape {
color: string;

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

abstract calculateArea(): number;

displayColor(): void {
console.log(`這個形狀是 ${this.color}`);
}
}

在這個範例中:

  • Shape是我們的抽象類別。
  • color是所有形狀都會有的屬性。
  • calculateArea()是一個抽象方法。注意它沒有方法體,只有聲明。
  • displayColor()是一個具體方法,所有形狀都可以使用。

現在,讓我們創建一些繼承我們Shape類別的特定形狀:

class Circle extends Shape {
radius: number;

constructor(color: string, radius: number) {
super(color);
this.radius = radius;
}

calculateArea(): number {
return Math.PI * this.radius * this.radius;
}
}

class Rectangle extends Shape {
width: number;
height: number;

constructor(color: string, width: number, height: number) {
super(color);
this.width = width;
this.height = height;
}

calculateArea(): number {
return this.width * this.height;
}
}

現在,我們可以使用這些類別:

const circle = new Circle("紅色", 5);
console.log(circle.calculateArea()); // 輸出: 78.53981633974483
circle.displayColor(); // 輸出: 這個形狀是 紅色

const rectangle = new Rectangle("藍色", 4, 6);
console.log(rectangle.calculateArea()); // 輸出: 24
rectangle.displayColor(); // 輸出: 這個形狀是 藍色

在這個範例中,CircleRectangle都繼承了Shape類別,並提供了他們自己的calculateArea()方法的實現。他們也從Shape類別繼承了displayColor()方法。

範例 2:Animal 抽象類別

讓我們創造另一個範例來加強我們的理解。這次,我們將創建一個抽象的Animal類別:

abstract class Animal {
name: string;

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

abstract makeSound(): void;

move(distance: number = 0): void {
console.log(`${this.name} 移動了 ${distance} 米。`);
}
}

class Dog extends Animal {
constructor(name: string) {
super(name);
}

makeSound(): void {
console.log("汪!汪!");
}
}

class Cat extends Animal {
constructor(name: string) {
super(name);
}

makeSound(): void {
console.log("喵!");
}
}

讓我們使用這些類別:

const dog = new Dog("Buddy");
dog.makeSound(); // 輸出: 汪!汪!
dog.move(10); // 輸出: Buddy 移動了 10 米。

const cat = new Cat("Whiskers");
cat.makeSound(); // 輸出: 喵!
cat.move(5); // 輸出: Whiskers 移動了 5 米。

在這個範例中,Animal是我們的抽象類別,帶有一個抽象的makeSound()方法和一個具體的move()方法。DogCat繼承了Animal並為makeSound()方法提供了他們自己的實現。

為什麼使用抽象類別?

你可能會想,「為什麼要這麼麻煩?為什麼不直接使用普通類別?」其實,抽象類別在你想為一組相關類別定義一個通用接口時非常有用。它們可以讓你:

  1. 為一組相關類別定義一個通用結構。
  2. 強制子類別實現某些方法。
  3. 提供所有子類別可以使用的某些通用功能。

把它看作是創建一個模板或合同,其他類別必須遵循。這是一種確保相關類別之間一致性的方法,同時在需要的地方允許定制。

抽象類別中的方法

這裡是一個表格,總結了你在抽象類別中可以有的方法類型:

方法類型 描述 可以在抽象類別上調用嗎? 子類別必須實現嗎?
抽象方法 聲明但沒有實現的方法
具體方法 完整實現的方法 否(可以被覆寫)

結論

好了,各位!我們已經一起穿越了TypeScript中的抽象類別領域。從理解它們是什麼,到創建它們,再到使用真實世界的範例來看它們是如何工作的,你現在已經對這個強大的TypeScript功能有了堅實的基礎。

記住,抽象類別就像建築的藍圖。它們提供了結構和一些細節,但具體的類別需要填充具體的內容,並將它們變得有生命力。

在你繼續你的程式設計旅程時,你會發現抽象類別是你的TypeScript工具箱中非常有用的工具。它們幫助你寫出更乾淨、更有組織、更易於維護的代碼。所以,勇敢地去抽象吧,盡情地去探索和學習!

快樂編程,直到下一次,我們繼續探索和學習!

Credits: Image by storyset