JavaScript 多态怎么实现?

文章导读
上一个 测验 下一个 JavaScript 中的多态 JavaScript 中的 polymorphism 允许你定义多个具有相同名称但不同功能的方法。多态通过方法 overloading 和 overriding 来实现。JavaScript 本身不支持方法 overlo
📋 目录
  1. JavaScript 中的多态
  2. 方法覆盖
  3. 示例
  4. 在 JavaScript 中使用多态的好处
A A

JavaScript - 多态



上一个
测验
下一个

JavaScript 中的多态

JavaScript 中的 polymorphism 允许你定义多个具有相同名称但不同功能的方法。多态通过方法 overloadingoverriding 来实现。JavaScript 本身不支持方法 overloading。方法 overriding 允许子类或派生类重新定义超类或父类的方法。在本章中,我们将使用方法 overriding 的概念来实现多态。

“Polymorphism”一词来源于 geek 术语“polymorph”。如果你拆解“polymorph”,其中“poly”意为“多”,“morph”意为从一种状态转变为另一种状态。

方法覆盖

在理解多态之前,理解方法覆盖非常重要。

如果你在父类和子类中定义了同名方法,则子类的方法会覆盖父类的方法。

例如,你想要计算不同形状的面积。你定义了一个包含 area() 方法的 Shape 类。现在,你为不同形状创建了不同的类,它们都扩展了 Shape 类,但你无法使用 Shape 类的 area() 方法来计算每个形状的面积,因为每种几何图形都有不同的面积计算公式。

因此,你需要在每个子类中定义 area() 方法,覆盖 Shape 类的 area() 方法,并计算特定形状的面积。这样,你就可以为单个方法创建多种形式。

示例

让我们通过下面的示例来理解多态和方法覆盖。

示例 1:演示 JavaScript 中的多态

在下面的示例中,Shape class 包含 area() method。Circle 和 Rectangle 这两个 class 都扩展了 Shape class。同时,Circle 和 Rectangle class 中也定义了 area() method。

下面的代码中定义了 3 个 area() method,但具体调用哪个 method 取决于你使用哪个 class 的实例来调用该 method。

<html>
<body>
   <div id = "output1"> </div>
   <div id = "output2"> </div>
   <script>
      class Shape {
         area(a, b) {
            return "The area of each Geometry is different! <br>"; // 每个几何图形的面积都不同!
         }
      }

      class Circle extends Shape {
         area(r) { // 覆盖 Shape class 的 method
            return "The area of Circle is " + (3.14 * r * r) + "<br>";
         }
      }

      class Rectangle extends Shape {
         area(l, b) { // 覆盖 Shape class 的 method
            return "The area of Rectangle is " + (l * b) + "<br>";
         }
      }

      const circle = new Circle();
      // 调用 Circle class 的 area() method
      document.getElementById("output1").innerHTML = circle.area(5); 
 
      const rectangle = new Rectangle();
      // 调用 Rectangle class 的 area() method
      document.getElementById("output2").innerHTML = rectangle.area(5, 10); 
   </script>
</body>
</html>

输出

The area of Circle is 78.5
The area of Rectangle is 50

通过这种方式,你可以定义具有不同功能的方法,并根据所需功能调用特定的方法。

你还可以在子 class 中使用 super 关键字调用父 class 的 method。让我们通过下面的示例来理解。

示例 2:在子 class 中扩展父 class method 的功能

在下面的示例中,Math 和 AdvanceMath class 都包含 mathOperations() method。

在 AdvanceMath class 的 mathOperations() method 中,我们使用了 super 关键字来调用父 class 的 mathOperations() method。我们在 AdvanceMath class 的 mathOperations() method 中扩展了 Math class 的 mathOperations() method 的功能。

此外,当你使用 Math class 的对象调用 mathOperation() method 时,它只会调用 Math class 的 method。

<html>
<body>
<p id = "output1"> </p>
<p id = "output2"> </p>
<script>
class Math {
    mathOperations(a, b) {
       document.getElementById("output1").innerHTML =  "Addition: " + (a+b) + "<br>";
       document.getElementById("output1").innerHTML += "Subtraction: " + (a-b);
    }
}

class AdvanceMath extends Math {
    mathOperations(a, b) {
       super.mathOperations(a, b);
       document.getElementById("output2").innerHTML += "Multiplication: " + (a*b) + "<br>";
       document.getElementById("output2").innerHTML += "Division: " + (a/b);
    }
}

const A_math = new AdvanceMath();
A_math.mathOperations(10, 5); // 调用 AdvanceMath class 的 method

</script>
</body>
</html>

输出

Addition: 15
Subtraction: 5

Multiplication: 50
Division: 2

这种多态被称为 运行时多态,因为 JavaScript 引擎会在运行时根据使用的 class 实例来决定执行哪个 method。

在 JavaScript 中使用多态的好处

在 JavaScript 中使用多态有很多优势;我们在这里解释了一些。

  • 代码可重用性 − 多态允许您重用代码。在第二个示例中,我们重用了 math 类中 mathOperations() 方法的代码。

  • 可扩展性 − 您可以轻松扩展当前代码并定义新功能。

  • 动态行为 − 您可以拥有多个包含相同方法但功能不同的类,并在运行时动态调用特定类的该方法。

您无法在 JavaScript 中实现编译时多态,因为无法重载方法。