JavaScript - 多态性
JavaScript 中的多态性
JavaScript 中的多态性允许您定义具有相同名称但功能不同的多个方法。多态性是通过方法重载和覆盖实现的。JavaScript 本身不支持方法重载。方法覆盖允许子类重新定义超类或父类的方法。在本章中,我们将使用方法覆盖的概念来实现多态性。
"多态性"一词源于极客词汇"polymorph"。如果将"多态性"拆分开来,"poly"表示"许多","morph"表示"从一种状态转换为另一种状态"。
方法重写
在理解多态性之前,理解方法重写非常重要。
如果在父类和子类中定义了同名的方法,子类方法将覆盖父类的方法。
例如,您想计算不同形状的面积。您定义了包含 area() 方法的 Shape 类。现在,您为不同的形状创建了不同的类,并且所有类都扩展了 Shape 类,但您无法使用 Shape 类的 area() 方法来计算每个形状的面积,因为每个几何体都有不同的面积计算公式。
因此,您需要在每个子类中定义 area() 方法,并重写 Shape 类的 area() 方法,然后计算特定形状的面积。这样,您可以创建单个方法的多种形式。
示例
让我们通过以下示例了解多态性和方法重写。
示例 1:演示 JavaScript 中的多态性
在下面的示例中,Shape 类包含 area() 方法。Circle 和 Rectangle 这两个类都扩展了 Shape 类。此外,area() 方法在 Circle 和 Rectangle 类中定义。
以下代码中定义了 3 个 area() 方法,但具体调用哪个方法取决于您使用哪个类的实例来调用该方法。
<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 类的方法
return "The area of Circle is " + (3.14 * r * r) + "<br>";
}
}
class Rectangle extends Shape {
area(l, b) { // 重写 Shape 类的方法
return "The area of Rectangle is " + (l * b) + "<br>";
}
}
const circle = new Circle();
// 调用 Circle 类的 area() 方法
document.getElementById("output1").innerHTML = circle.area(5);
const rectangle = new Rectangle();
// 调用 Rectangle 类的 area() 方法
document.getElementById("output2").innerHTML = rectangle.area(5, 10);
</script>
</body>
</html>
输出
The area of Circle is 78.5 The area of Rectangle is 50
这样,您可以定义具有不同功能的相同方法,并根据所需功能调用特定方法。
您还可以使用 super 关键字在子类中调用父类方法。让我们通过以下示例来理解。
示例 2:在子类中扩展父类方法的功能
以下示例中,Math 和 AdvanceMath 类包含 mathOperations() 方法。
在 AdvanceMath 类的 mathOperations() 方法中,我们使用 super 关键字调用父类的 mathOperations() 方法。我们在 AdvanceMath 类的 mathOperations() 方法中扩展了 math 类的 mathOperations() 方法的功能。
此外,当您使用 Math 类的对象调用 mathOperation() 方法时,它只会调用 Math 类的方法。
<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 类的方法
</script>
</body>
</html>
输出
Addition: 15 Subtraction: 5 Multiplication: 50 Division: 2
这种多态性称为运行时多态性,因为 JavaScript 引擎会根据所使用的类的实例来决定在运行时执行哪个方法。
在 JavaScript 中使用多态性的好处
在 JavaScript 中使用多态性有很多好处;我们在这里解释了其中的一些。
代码可重用性 − 多态性允许您重用代码。在第二个示例中,我们重用了 math 类的 mathOperations() 方法的代码。
可扩展性 − 您可以轻松扩展当前代码并定义新功能。
动态行为 − 您可以拥有多个包含相同方法但功能不同的类,并在运行时动态调用特定类的方法。
由于您无法重载方法,因此无法在 JavaScript 中实现编译时多态性。

