多型

Frontend SELF TW
等級 40 , 課堂 3
開放

10.1 多型的基礎

多型是物件導向程式設計(OOP)中的一個關鍵概念。從廣義來說,多型允許不同類別的物件使用同一個介面來處理資料。 在JavaScript的上下文中,這意味著不同的物件可以具有相同名稱的方法,而這些方法可以在不知道其具體類型的情況下調用在物件上。

多型的類型

在JavaScript中,主要的多型類型有:

1. Ad-hoc 多型 (ad-hoc polymorphism):

  • 方法的多型,對不同類型的物件調用具有相同名稱的方法
  • 例如函數和運算子的重載(這在JavaScript中不被直接支持,但可以被模擬)

2. 子類型多型 (Subtype polymorphism):

  • 子類型或包含多型,當不同類別的物件繼承自同一個基類時,可以被當作基類物件來處理
  • 這是透過繼承和介面來實現的主要多型類型

多型的優點:

  1. 簡化代碼: 多型允許撰寫更靈活和通用的代碼,可以處理不同類別的物件,無需知道其具體類型。
  2. 擴展性: 多型使得可以在不改變現有代碼的情況下向系統添加新類型和行為。
  3. 支持性: 多型促進了職責的更好區分,提升代碼的可讀性和支持性。

10.2 JavaScript中的多型示例

透過繼承實現的子類型多型

示例 1: 使用一個介面處理不同類型的物件

在這個例子中,函數playWithAnimal接受一個Animal類型的物件並調用方法makeSoundDogCat物件繼承自Animal,且覆蓋makeSound方法,並在每個物件調用該方法時,產生不同的結果。

JavaScript
    
      class Animal {
        makeSound() {
          console.log('Some generic sound');
        }
      }

      class Dog extends Animal {
        makeSound() {
          console.log('Woof!');
        }
      }

      class Cat extends Animal {
        makeSound() {
          console.log('Meow!');
        }
      }

      function playWithAnimal(animal) {
        animal.makeSound();
      }

      const dog = new Dog();
      const cat = new Cat();

      playWithAnimal(dog); // 會顯示: Woof!
      playWithAnimal(cat); // 會顯示: Meow!
    
  

10.3 通過介面實現多型 (Duck Typing)

在JavaScript中沒有像TypeScript或Java那樣的內建介面支持。取而代之的是使用一種叫做「鴨子類型」(Duck Typing)的方法。 這意味著,只要物件具備所需的方法和屬性,就被認為符合介面要求,而不管其具體類型或繼承。

重要!

鴨子法則 (duck): 如果某物看起來像鴨子,又游得像鴨子,還叫得像鴨子,那它很可能就是鴨子。

示例 2: 使用鴨子類型

在這個例子中,函數takeOff接受任何具有fly方法的物件。BirdAirplane物件實現了fly方法,因此可以傳遞給takeOff

JavaScript
    
      class Bird {
        fly() {
          console.log('Flying...');
        }
      }

      class Airplane {
        fly() {
          console.log('Jet engine roaring...');
        }
      }

      function takeOff(flyingObject) {
        flyingObject.fly();
      }

      const bird = new Bird();
      const airplane = new Airplane();

      takeOff(bird);      // 會顯示: Flying...
      takeOff(airplane);  // 會顯示: Jet engine roaring...
    
  

10.4 通過函數實現多型

在JavaScript中,函數是頭等對象,可以傳遞和用於實現多型行為。

示例 3: 通過函數實現多型

在這個例子中,函數greet接受另一個函數作為參數並調用它。這允許使用不同的函數來執行不同的操作。

JavaScript
    
      function greetMorning() {
        console.log('Good morning!');
      }

      function greetEvening() {
        console.log('Good evening!');
      }

      function greet(greetingFunction) {
        greetingFunction();
      }

      greet(greetMorning); // 會顯示: Good morning!
      greet(greetEvening); // 會顯示: Good evening!
    
  

10.5 通過方法重載實現多型 (模擬)

JavaScript不支持直接的方法重載,如同其他一些程式語言。然而,可以通過函數參數和類型檢查來模擬方法重載。

示例 4: 模擬方法重載

在這個例子中,方法add接受兩個參數並根據其類型執行不同的操作。如果參數是數字,則方法做加法。如果參數是數組,則方法合併它們。

JavaScript
    
      class Calculator {
        add(a, b) {
          if (typeof a === 'number' && typeof b === 'number') {
            return a + b;
          } else if (Array.isArray(a) && Array.isArray(b)) {
            return a.concat(b);
          } else {
            throw new Error('Invalid arguments');
          }
        }
      }

      const calc = new Calculator();
      console.log(calc.add(1, 2));           // 會顯示: 3
      console.log(calc.add([1, 2], [3, 4])); // 會顯示: [1, 2, 3, 4]
    
  
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION