JavaScript - Polymorphism(多态性)



JavaScript 中的多态性

JavaScript 中的 Polymorphism(多态性) 允许您定义具有相同名称和不同功能的多个方法。多态性是通过使用方法 重载 和 重写 来实现的。JavaScript 本身不支持方法重载。方法覆盖允许子类或子类重新定义超类或父类的方法。在本章中,我们将使用方法覆盖的概念实现多态性。

polymorphism 词源自极客词 polymorph。如果你打破了 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) { // 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 关键字调用 child 类中的 parent 类方法。让我们通过下面的示例来理解它。

示例 2:Child Class 中 Parent 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

这种类型的多态性称为运行时多态性,因为 JavaScript 引擎根据使用的类的实例来决定在运行时应该执行哪种方法。

在 JavaScript 中使用多态性的好处

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

  • 代码可重用性 − 多态性允许您重用代码。在第二个示例中,我们重用了 math 类的 mathOperations() 方法的代码。
  • 可扩展性 - 您可以轻松扩展当前代码并定义新功能。
  • 动态行为 − 您可以拥有多个类,其中包含具有不同功能的相同方法,并在运行时动态调用特定类的方法。
你不能在 JavaScript 中实现编译时多态性,因为你不能重载该方法。