TypeScript 中的類別
本文解釋了 TypeScript 中的類別。
YouTube Video
TypeScript 中的類別
TypeScript 的類別基於 JavaScript 的 ES6 類別,並提供類型註解和訪問修飾符等額外功能。這使您能利用面向對象編程的概念,同時確保更強健和清晰的類型安全性。
以下是 TypeScript 中類別的基本用法和功能解釋。
基本類別定義
1class Person {
2 name: string; // Member variable
3 age: number; // Member variable
4
5 // Constructor
6 constructor(name: string, age: number) {
7 this.name = name;
8 this.age = age;
9 }
10
11 // Method
12 greet(): void {
13 console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
14 }
15}
16
17const person = new Person("Alice", 25);
18person.greet(); // Hello, my name is Alice and I am 25 years old.
name和age是類別的屬性(成員變量)。constructor是創建類別實例時調用的方法,該方法接收參數並將值分配給屬性。greet是類別的一個方法,其類型為void,表明它沒有返回值。
訪問修飾符
在 TypeScript 中,您可以使用訪問修飾符(public、private、protected)來控制對類別屬性和方法的訪問。
public
默認情況下,所有屬性和方法都是 public 的。這意味著它們可以從類別外部訪問。
1class Animal {
2 public species: string;
3
4 constructor(species: string) {
5 this.species = species;
6 }
7
8 public makeSound(): void {
9 console.log(`${this.species} makes a sound.`);
10 }
11}
12
13const animal = new Animal("Dog");
14console.log(animal.species); // Dog
15animal.makeSound(); // Dog makes a sound.
species屬性和makeSound方法被宣告為public,可以從類別外部存取。
private
使用 private 修飾符可防止從類別外部訪問屬性或方法。
1class Car {
2 private brand: string;
3
4 constructor(brand: string) {
5 this.brand = brand;
6 }
7
8 public getBrand(): string {
9 return this.brand;
10 }
11}
12
13const car = new Car("Toyota");
14// console.log(car.brand); // Error: 'brand' is private and cannot be accessed.
15console.log(car.getBrand()); // Toyota
brand屬性被宣告為private,所以無法從類別外部存取。- 使用
private修飾詞隱藏屬性可以實現資料封裝。
protected
protected 修飾符限制從類別外部訪問,但允許在子類(派生類別)中訪問。
1class Vehicle {
2 protected model: string;
3
4 constructor(model: string) {
5 this.model = model;
6 }
7}
8
9class Truck extends Vehicle {
10 public getModel(): string {
11 return this.model;
12 }
13}
14
15const truck = new Truck("Ford F-150");
16console.log(truck.getModel()); // Ford F-150
17
18// console.log(truck.model);
19// Error: Property 'model' is protected and only accessible within class 'Vehicle' and its subclasses.
model屬性被宣告為protected,因此無法從類別外部存取,但可以從子類別存取。
Getter 和 Setter
在 TypeScript 中,您可以使用 get 和 set 關鍵字定義 Getter 和 Setter,以獲取和設置屬性值。
1class Employee {
2 private _salary: number;
3
4 constructor(salary: number) {
5 this._salary = salary;
6 }
7
8 // Getter
9 get salary(): number {
10 return this._salary;
11 }
12
13 // Setter
14 set salary(newSalary: number) {
15 if (newSalary > 0) {
16 this._salary = newSalary;
17 } else {
18 console.log("Salary must be positive.");
19 }
20 }
21}
22
23const employee = new Employee(50000);
24console.log(employee.salary); // 50000
25employee.salary = 60000;
26console.log(employee.salary); // 60000
27employee.salary = -100; // Salary must be positive.
- 在這個範例中,對
salary屬性使用 getter 和 setter 來控制外部存取與更新。setter 會執行驗證以防止負值,如果提供了無效的值則顯示警告訊息。
繼承
在 TypeScript 中,類別可以被繼承。使用 extends 關鍵字,您可以從父類別繼承功能。
1class Animal {
2 constructor(public name: string) {}
3
4 public move(): void {
5 console.log(`${this.name} is moving.`);
6 }
7}
8
9class Bird extends Animal {
10 public fly(): void {
11 console.log(`${this.name} is flying.`);
12 }
13}
14
15const bird = new Bird("Sparrow");
16bird.move(); // Sparrow is moving.
17bird.fly(); // Sparrow is flying.
- 在這個範例中,
Bird類別繼承自Animal類別,因此可以使用Animal的move方法。此外,它定義了自己的fly方法,在繼承父類別功能的同時新增新功能。
抽象類別
抽象類別(abstract)不能直接實例化,並用作模板以在子類別中提供具體實現。
1abstract class Shape {
2 abstract getArea(): number;
3
4 public describe(): void {
5 console.log("This is a shape.");
6 }
7}
8
9class Circle extends Shape {
10 constructor(private radius: number) {
11 super();
12 }
13
14 public getArea(): number {
15 return Math.PI * this.radius * this.radius;
16 }
17}
18
19const circle = new Circle(5);
20console.log(circle.getArea()); // 78.53981633974483
21circle.describe(); // This is a shape.
- 在這個範例中,
Shape被定義為抽象類別,getArea是必須被子類別實作的抽象方法。Circle類別繼承這個抽象類別,並實作自己用來計算圓面積的getArea方法。此外,像describe這樣的具體方法也被子類繼承作為共用功能,並可直接使用。
與介面的關係
類別可以實現介面,確保它們具有特定的屬性和方法。
1interface Flyable {
2 fly(): void;
3}
4
5class Airplane implements Flyable {
6 public fly(): void {
7 console.log("The airplane is flying.");
8 }
9}
10
11const airplane: Flyable = new Airplane();
12airplane.fly(); // The airplane is flying.
- 在這個範例中,
Flyable介面定義了fly方法的規範,而Airplane類別則透過具體實作fly方法來實現此介面。如此一來,任何可以視為Flyable型別的物件都保證會有fly方法。
靜態成員
當在類別中定義靜態成員時,這些方法和屬性是隸屬於類別本身的。靜態成員可以在不實例化類別的情況下被呼叫。
1class MathUtils {
2 static PI: number = 3.14;
3
4 static add(a: number, b: number): number {
5 return a + b;
6 }
7}
8
9console.log(MathUtils.add(10, 20)); // 30
10console.log(MathUtils.PI); // 3.14
- 你可以使用
static關鍵字定義靜態方法。 - 在這個範例中,
MathUtils類別定義了一個靜態方法add和一個靜態屬性PI。 - 靜態成員不屬於類別的實例,而是可以從類別本身直接呼叫。
總結
TypeScript 類別為 JavaScript 的類別功能新增了類型安全、存取修飾符和抽象類別等功能。這使得物件導向程式設計更加強大且安全。
您可以在我們的 YouTube 頻道上使用 Visual Studio Code 來跟隨上述文章一起學習。 請也查看我們的 YouTube 頻道。