Javascript 简明教程
JavaScript - Polymorphism
Polymorphism in JavaScript
polymorphism 在 JavaScript 中使你能够定义多个具有相同名称和不同功能的方法。通过使用 overloading 和 overriding 方法来实现多态性。JavaScript 本身不支持方法重载。方法重写允许子类或子类重新定义超类或父类的方法。在本章中,我们将使用方法重写的概念来实现多态性。
多态性一词源自极客术语 polymorph。如果你拆分 polymorph,则“poly”的意思是许多,“morph”的意思是从一种状态转换为另一种状态。
Method Overriding
在理解多态性之前,了解方法覆盖非常重要。
如果在父类和子类中定义一个具有相同名称的方法,则子类方法会覆盖父类的方法。
例如,你想要计算不同形状的面积。你已经定义了包含 area() 方法的 Shape 类。现在,你为不同的形状有不同的类,并且所有这些类都扩展 Shape 类,但是你不能使用 Shape 类的 area() 方法来找到每个形状的面积,因为每个几何形状都有不同的面积计算公式。
所以,你需要在每个子类中定义 area() 方法,覆盖 Shape 类的 area() 方法,然后找到特定形状的面积。通过这种方式,你可以创建单个方法的多种形式。
Examples
让我们通过下面的示例来理解多态性和方法覆盖。
Example 1: Demonstrating Polymorphism in 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) { // Overriding the method of the Shape class
return "The area of Circle is " + (3.14 * r * r) + "<br>";
}
}
class Rectangle extends Shape {
area(l, b) { // Overriding the method of the Shape class
return "The area of Rectangle is " + (l * b) + "<br>";
}
}
const circle = new Circle();
// Calling area() method of Circle class
document.getElementById("output1").innerHTML = circle.area(5);
const rectangle = new Rectangle();
// Calling area() method of Rectangle class
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 关键字在子类中调用父类方法。让我们通过下面的示例来理解它。
Example 2: Parent Class Method’s Functionality Extension in Child Class
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); // Calls method of AdvanceMath class
</script>
</body>
</html>
Addition: 15
Subtraction: 5
Multiplication: 50
Division: 2
这种多态性类型被称为 runtime polymorphism ,这是因为 JavaScript 引擎根据使用哪个类的实例来决定在运行时应该执行哪个方法。