多态

Frontend SELF ZH
第 40 级 , 课程 3
可用

10.1 多态的基础

多态是面向对象编程 (OOP) 的核心概念之一。简单来说,多态让不同类的对象可以通过同一个接口来处理数据。在 JavaScript 的语境中,这意味着不同的对象可以有相同名字的方法,而且这些方法可以在不知道对象具体类型的情况下被调用。

多态的类型

在 JavaScript 中,主要的多态类型有:

1. 特设多态 (ad-hoc polymorphism):

  • 方法的多态性,为不同类型的对象调用相同名字的方法
  • 例子包括函数重载和运算符重载(这在 JavaScript 中不直接支持,但可以模拟)

2. 子类型多态 (Subtype polymorphism):

  • 子类型多态或包含,当不同类的对象继承于同一个基类时,可以作为基类的对象来处理
  • 这是通过继承和接口实现的主要多态类型

多态的优势:

  1. 简化代码: 多态允许编写更灵活和通用的代码,可以处理不同类型的对象而无需知道它们的具体类型。
  2. 扩展性: 多态使得在系统中添加新类型和行为变得更容易,而不需要修改已有代码。
  3. 支持: 多态有助于更好地分工并提高代码的可读性和可维护性。

10.2 JavaScript 中的多态示例

通过继承实现的子类型多态

示例 1:使用一个接口处理不同类型的对象

在这个例子中,playWithAnimal函数接收一个Animal类型的对象并调用makeSound方法。继承自AnimalDogCat对象重写了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