iT邦幫忙

2024 iThome 鐵人賽

DAY 18
0
JavaScript

我推的TypeScript 操作大全系列 第 18

我推Day18 - TypeScript 超能力解鎖:物件導向與模組的完美結合

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20241002/20124462mLOJVNQOLW.jpg


學會 TypeScript 的類別與模組,打造無懈可擊的程式架構

你是不是在專案越來越大時,覺得 TypeScript 的程式碼難以保持邏輯與維護呢?🤔
不用擔心,class(類別)和 module(模組)是你的救星!

今天我們將深入探討 TypeScript 中的物件導向程式設計,並發現如何使用 classmodule 來建立結構化且可重用的程式碼。
從繼承、存取修飾符(access modifiers)到抽象類別(abstract class)和命名空間(namespace),你將學習到這些重要概念,幫助你提升 TypeScript 技能,打造可擴展且易於維護的應用程式。

準備來掌握這些技巧吧!💪🚀


物件導向程式設計:class 和 module 大解析

在你對 TypeScript 型別已有的理解基礎上,這篇文章將進一步介紹 class(類別)與 module(模組)這兩個對於大型專案開發者至關重要的概念。
這些功能不僅與傳統的物件導向程式設計(OOP)完美契合,還透過封裝(encapsulation)和模組化(modularization)來提升程式碼的組織性與重用性,讓專案更易於維護和擴展。


類別與繼承:打造靈活可擴展的程式架構

在 TypeScript 的物件導向設計中,class(類別)是用來描述物件的結構和行為的關鍵工具。它能夠將相關的屬性(properties)和方法(methods)整合在一起,讓我們能夠更直觀、模組化地組織程式碼。

  • 繼承的概念

繼承(inheritance)是物件導向程式設計的核心概念之一,通過它,開發者可以讓一個類別繼承另一個類別的屬性和方法。這樣做的好處是:

  1. 程式碼重用:你可以建立通用的父類別,並將其行為與屬性傳遞給子類別,避免重複程式碼的出現。
  2. 靈活擴展:子類別可以覆寫(override)父類別的方法,或是新增屬性和功能,來適應不同的需求,這使得應用程式更具可擴展性。
  3. 更易維護:當父類別的邏輯發生變化時,這些變化將自動反映到所有子類別,減少了維護的複雜度。

實際範例:動物與蛇

下面的範例展示了如何使用 class 和繼承來描述不同的動物行為。

class Animal {
  name: string;

  // 建構函式 constructor 用於初始化物件的 name 屬性
  constructor(name: string) {
    this.name = name;
  }

  // move 方法表示動物的移動行為
  move(distanceInMeters: number): void {
    console.log(`${this.name} moved ${distanceInMeters}m.`);
  }
}

class Snake extends Animal {
  constructor(name: string) {
    // 使用 super 呼叫父類別的 constructor
    super(name);
  }

  // 覆寫父類別的 move 方法,並提供默認值
  move(distanceInMeters = 5): void {
    console.log("Slithering...");
    super.move(distanceInMeters); // 呼叫父類別的 move 方法
  }
}

在這個範例中,我們定義了一個 Animal 類別,並繼承了一個 Snake 類別:

  1. 父類別 Animal:定義了所有動物共用的屬性 name 和方法 movemove 方法接收距離參數,並輸出動物移動的訊息。
  2. 子類別 Snake:繼承了 Animal 的屬性和方法,並在它的 move 方法中進行了覆寫(override),增加了一個特定於蛇的行為 "Slithering...",然後呼叫了父類別的 move 方法來保持基本的移動行為。

應用場景:TypeScript 中類別與繼承的實際應用

建立有組織的程式架構

class 和繼承在實際專案中有非常廣泛的應用,特別是當專案變得越來越大時,能夠建立良好組織的程式架構是至關重要的。
透過繼承,我們可以為程式設計出一個「基礎架構」,讓各種不同的實體(如動物、交通工具、角色等)共用基礎功能,並在子類別中進行擴展或覆寫。

促進程式碼的重用性

假設我們正在開發一個大型應用程式,這個應用程式中有多種不同的動物,每種動物的行為可能略有不同。與其為每一個動物類別重複撰寫相同的移動邏輯,我們可以使用繼承來定義一個通用的 Animal 類別,然後讓其他動物類別(如 SnakeBird)繼承這個基礎類別,並根據需要覆寫特定行為。

例如,除了蛇之外,我們還可以定義一個 Bird 類別,讓它繼承 Animal,並覆寫 move 方法來加入飛翔的邏輯:

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

  move(distanceInMeters = 10): void {
    console.log("Flying...");
    super.move(distanceInMeters);
  }
}

這樣做不僅提高了程式碼的重用性,還確保了不同類別之間的行為一致性。
我們可以很輕鬆地修改父類別的邏輯,並且這些修改會自動反映到所有子類別上,減少了重複修正的工作。

易於維護與擴展

隨著專案的擴展,開發者可以輕鬆新增更多的子類別或修改父類別的邏輯,而不會影響現有的程式碼。這使得應用程式能夠快速適應變化,保持穩定的基礎架構,同時也為未來的擴展提供了足夠的彈性。


存取修飾符:public、private 和 protected

TypeScript 中的 publicprivateprotected 存取修飾符(access modifiers)為我們提供了控制類別成員可見性和訪問範圍的工具。這讓開發者可以更好地封裝(encapsulation)類別內部的資料,保護物件的狀態,並只公開必要的部分。

publicprivateprotected 的作用

  1. public(公開):public 成員可以在類別內、類別外以及子類別中被訪問。它是 TypeScript 的預設修飾符,若未顯式聲明,類別成員即為 public

  2. private(私有):private 成員只能在類別內部被訪問,無法從外部或子類別中直接存取。這有助於防止程式碼在無意中修改或直接操作類別的內部狀態。

  3. protected(受保護):protected 成員可以在類別內部和子類別中被訪問,但無法從類別外部直接存取。這在父子類別間共享資料的情境下特別有用。

實際範例:動物類別中的存取控制

以下範例展示了如何使用 privatepublic 修飾符來控制類別的成員可見性。

class Animal {
  // 使用 private 將 name 屬性設為私有
  private name: string;

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

  // 使用 public 讓 move 方法可以從類別外部訪問
  public move(distanceInMeters: number): void {
    console.log(`${this.name} moved ${distanceInMeters}m.`);
  }
}

在這段程式碼中:

  • name 被設定為 private,因此只能在 Animal 類別內被存取,無法從外部修改。
  • move 方法是 public,允許外部使用者呼叫並執行這個方法。

應用場景:

存取修飾符非常適合用來保護類別內的私有資料,例如一個物件的內部狀態不應被外部隨意修改。
這樣的封裝方式可以保護應用程式免受意外的變更,同時也讓開發者更清楚哪些成員是公開的,哪些是應該保護的。

例如,在一個銀行系統中,我們可以用 private 修飾符來保護客戶的敏感資訊(如銀行賬號),只允許某些方法來處理這些資料,而不是讓外部系統直接修改它。


抽象類別與介面

抽象類別(abstract class)是 TypeScript 中另一個重要的物件導向功能,它提供了一個藍圖,讓開發者能夠定義必須在子類別中實作的通用方法。
與一般類別不同,抽象類別無法直接實例化,它們只能作為其他類別的基礎。

抽象類別的特性

  1. 不能實例化:抽象類別只能作為基礎類別,無法被直接用來創建物件。例如,無法直接 new Department(),必須透過衍生類別來實作。

  2. 抽象方法:抽象方法必須在子類別中實作,抽象方法沒有具體的實作內容,只提供一個結構讓子類別來實作具體邏輯。這讓開發者能夠定義一組標準,保證所有子類別都會遵循這些規則。

實際範例:部門類別

以下範例展示了一個抽象類別 Department,其中包含一個必須由子類別實作的抽象方法 printMeeting

abstract class Department {
  // 定義部門名稱屬性,並使用建構函式進行初始化
  constructor(public name: string) {}

  // 普通方法,可供子類別直接使用
  printName(): void {
    console.log("Department name: " + this.name);
  }

  // 抽象方法,必須在衍生類別中實作
  abstract printMeeting(): void;
}

// 衍生類別必須實作抽象方法
class ITDepartment extends Department {
  constructor() {
    super("IT Department");
  }

  printMeeting(): void {
    console.log("The IT department meeting is scheduled at 10 AM.");
  }
}

在這裡:

  • Department 是一個抽象類別,定義了 printName 方法(可直接使用),並強制要求衍生類別實作 printMeeting 方法。
  • ITDepartment 是一個具體的類別,繼承自 Department,並實作了 printMeeting 方法。

應用場景:

抽象類別適合用來定義某些通用行為和結構,並要求具體的衍生類別提供實作。例如,在大型應用中,我們可以使用抽象類別來定義不同類型使用者的共同行為,像是員工和管理者的登入邏輯,然後透過不同的子類別來處理具體的角色行為。


模組與命名空間

在 TypeScript 中,module(模組)是一個非常強大的功能,幫助開發者將程式碼組織成更小、更具模組化的部分。
模組允許開發者將程式碼分隔成不同的檔案,並透過 exportimport 來共享類別、介面、函式等。

模組的優勢

  1. 提升可維護性:模組可以將程式碼拆分成易於管理的部分,這樣可以避免將所有邏輯寫在同一個檔案中,從而提升程式碼的可讀性與維護性。

  2. 避免命名衝突:模組中的程式碼會被封裝起來,避免與其他模組發生命名衝突。這讓開發者可以使用相同名稱的變數或類別,而不會擔心覆蓋問題。

  3. 促進重用性:透過 export 將類別或功能從模組中導出,其他檔案可以 import 這些功能並重用,讓程式碼更具模組化。

實際範例:模組化的形狀類別

以下範例展示了如何使用模組來分離和重用程式碼。

// 在檔案 Shape.ts 中定義 Rectangle 類別,並使用 export 將其導出
export class Rectangle {
  constructor(public width: number, public height: number) {}

  // 計算矩形面積的方法
  area(): number {
    return this.width * this.height;
  }
}

// 在檔案 App.ts 中,import Rectangle 並使用
import { Rectangle } from "./Shape";
let myRectangle = new Rectangle(5, 3);
console.log(myRectangle.area()); // 輸出: 15

在這裡:

  • Rectangle 類別定義在 Shape.ts 檔案中,並使用 export 將其導出,允許其他模組或檔案使用。
  • App.ts 中,我們透過 importRectangle 引入並使用它來創建矩形物件,進行面積計算。

應用場景:

模組非常適合用來拆分大型專案,特別是在多人開發的環境中,模組化能夠讓團隊更清晰地分工和合作。
例如,你可以將專案中的每個功能區塊(如使用者管理、產品列表等)拆分為不同的模組,每個模組負責一個單一的功能,並透過 exportimport 將功能整合到一起,這樣就能讓專案更具結構性且更易維護。


總結:掌握 TypeScript 物件導向特性

  • 類別與繼承 幫助我們建立靈活的應用架構,減少重複程式碼,提升專案的可維護性與可擴展性。
  • 存取修飾符 提供了封裝與安全性,保護類別內部資料的完整性。
  • 抽象類別 定義了通用邏輯與行為,強制不同類別遵守共同的結構。
  • 模組 則是組織與共享程式碼的強大工具,讓專案更加模組化、易於維護且具可重用性。

今天的程式碼寫得越好,明天的你就越輕鬆!🌟💻
所以別偷懶,繼續優化每一行程式碼吧~未來的你一定會感謝現在的自己!🚀😊


上一篇
我推Day17 - 型別安全大升級!用 TypeScript 防禦你的程式世界
下一篇
我推Day19 - 學會 TypeScript 的 using,讓程式碼優雅無壓力
系列文
我推的TypeScript 操作大全30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言