iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0
Modern Web

TypeScript 魔法 - 喚醒你的程式碼靈感系列 第 24

Day24 - 實作介面與類別

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20231009/20152047nbpEuA2fb9.png

先前學習過,介面(interfaces)不僅可以用於描述「物件的形狀」,同時也可用來抽象類別的一部分行為。

類別實作介面

在 TypeScript 中,透過使用 implements 關鍵字,我們可以將一個類別與一個介面相關聯,以確保該類別遵循該介面所規定的標準。這表示該類別必須實現介面中定義的所有屬性和方法,以確保它達到所期望的行為。

使用 interface 定義類別後,再用 class Implements 類別實作

// 定義一個介面 Greetable
interface Greetable {
  name: string;

  greet(phrase: string): void;
}

// 實作 Greetable 介面的類別 Person
class Person implements Greetable {
  name: string;
  age = 30; // 新增的其他屬性

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

  greet(phrase: string) {
    console.log(`${phrase}${this.name}`); // 大家好,我是肉鬆
  }
}

// 建立 Person 物件的實例
const person = new Person('肉鬆');
person.greet('大家好,我是');

在這個範例中,我們首先定義了一個 Greetable 介面,其中包含一個 greet 方法的定義。接著,我們建立了一個 Person 類別,並使用 implements 關鍵字來實現 Greetable 介面的要求。

這意味著 Person 類別必須提供 greet 方法的具體實作,以確保它符合 Greetable 介面的規範。如果我們忘記在 Person 類別中實作 greet 方法,TypeScript 會產生錯誤訊息。

多介面實作

除了實作單一介面,我們也可以在一個類別中實作多個介面。這樣做可以讓我們將多個規範結合在一個類別中,並確保它滿足所有這些規範。

interface Greetable {
  name: string;

  greet(phrase: string): void;
}

interface Nameable {
  getName(name: string): void;
}

class Person implements Greetable, Nameable {
  name: string;
  age = 30;

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

  greet(phrase: string) {
    console.log(`${phrase}${this.name}`); // 大家好,我是肉鬆
  }

  getName(name: string) {
    this.name = name;
    console.log(name); // 傑尼龜
  }
}

const person = new Person('肉鬆');
person.greet('大家好,我是');
person.getName('傑尼龜');

在這個範例中,我們定義了兩個介面,即 GreetableNameable。然後,我們在 Person 類別中使用 implements 關鍵字來實現這兩個介面。這表示 Person 類別必須提供 name 屬性、greet 方法以及 getName 方法的具體實作。

介面繼承類別

介面不僅可以繼承其他介面,還可以繼承類別。

// 定義一個類別 Person
class Person {
  name: string;
  age: number;

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

  greet() {
    console.log(`大家好,我是${this.name},今年${this.age}歲`);
  }
}

// 定義一個介面 PersonInfo,繼承 Person 類別
interface PersonInfo extends Person {
  getInfo(): string;
}

// 實作 PersonInfo 介面的類別
class DetailedPerson implements PersonInfo {
  name: string;
  age: number;
  profession: string;

  constructor(name: string, age: number, profession: string) {
    this.name = name;
    this.age = age;
    this.profession = profession;
  }

  greet(): void {
    console.log(`大家好,我是${this.name},今年${this.age}歲,是一名${this.profession}`);
    // 大家好,我是肉鬆,今年30歲,是一名前端工程師
  }

  getInfo(): string {
    return `姓名:${this.name},年齡:${this.age},職業:${this.profession}`;
  }
}

const person = new DetailedPerson('肉鬆', 30, '前端工程師');
person.greet();
console.log(person.getInfo()); // 姓名:肉鬆,年齡:30,職業:前端工程師

在這個範例中,我們首先定義了一個名為 Person 的類別,它包含 nameage 屬性,以及 greet 方法。接著,我們定義了一個介面 PersonInfo,該介面擴展了 Person 類別,同時新增了一個名為 getInfo 的新方法。

最後,我們建立了一個 DetailedPerson 類別,它實現了 PersonInfo 介面,同時繼承了 Person 類別。這使得 DetailedPerson 類別需要提供 getInfo 方法的具體實現,並且可以使用 greet 方法,因為它繼承了 Person 類別的屬性和方法。

本日重點

  1. 使用 implements 關鍵字,可以將一個類別與一個介面關聯,以實現該介面所定義的內容。
  2. 不僅可以實作單一介面,還可以實作多個介面,使一個類別同時具備多個介面所定義的特性。
  3. 介面不僅可以繼承其他介面,還可以繼承類別的特性。

參考


上一篇
Day23 - 建立物件藍圖 - 類別(class)
下一篇
Day25 - 泛型(Generics)上篇 - 讓程式碼變得更通用!
系列文
TypeScript 魔法 - 喚醒你的程式碼靈感30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言