JavaScript 中的多态允许你定义具有相同名称但不同功能的多个方法。多态是通过方法重载和覆盖来实现的。JavaScript 本身并不支持方法重载。方法覆盖允许子类或子类重新定义超类或父类的方法。在本章中,我们将通过方法覆盖的概念来实现多态。
“多态”这个词来源于希腊语 polymorph。如果你拆解 polymorph,'poly' 的意思是很多,而 'morph' 的意思是状态的转换。
方法覆盖
在理解多态之前,重要的是要理解方法覆盖。
如果你在父类和子类中定义了同名的方法,那么子类的方法将会覆盖父类的方法。
例如,你想计算不同形状的面积。你定义了一个包含 area()
方法的 Shape
类。现在,对于不同的形状,你有不同的类,并且它们都扩展了 Shape
类,但是你不能使用 Shape
类中的 area()
方法来计算每个形状的面积,因为每个几何图形都有一个不同的公式来计算面积。
因此,你需要在每个子类中定义 area()
方法,覆盖 Shape
类的 area()
方法,并找到特定形状的面积。这样,你可以创建单一方法的多种形式。
示例
让我们通过下面的例子来理解多态和方法覆盖。
示例 1:演示 JavaScript 中的多态
在下面的例子中,Shape
类包含 area()
方法。Circle
和 Rectangle
类都扩展了 Shape
类。并且在 Circle
和 Rectangle
类中定义了 area()
方法。
虽然下面的代码中有三个 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) {
return "The area of Circle is " + (3.14 * r * r) + "<br>";
}
}
class Rectangle extends Shape {
area(l, b) {
return "The area of Rectangle is " + (l * b) + "<br>";
}
}
const circle = new Circle();
document.getElementById("output1").innerHTML = circle.area(5);
const rectangle = new Rectangle();
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);
</script>
</body>
</html>
输出:
Addition: 15
Subtraction: 5
Multiplication: 50
Division: 2
这种多态称为运行时多态,因为在运行时,JavaScript 引擎会根据使用的类的实例决定应该执行哪个方法。
在 JavaScript 中使用多态的优势
在 JavaScript 中使用多态有很多优点;我们在这里解释了一些。
-
代码重用性 - 多态允许你重用代码。在第二个例子中,我们重用了
Math
类的 mathOperations()
方法的代码。
-
可扩展性 - 你可以轻松地扩展当前代码并定义新功能。
-
动态行为 - 你可以拥有包含相同方法但具有不同功能的多个类,并在运行时动态地调用特定类的方法。
你无法在 JavaScript 中实现编译时多态,因为你无法重载方法。