Javascript 简明教程

JavaScript - Polymorphism

Polymorphism in JavaScript

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

The polymorphism in JavaScript allows you to define multiple methods with the same name and different functionalities. Polymorphism is achieved by using method overloading and overriding. JavaScript does not support method overloading natively. Method overriding allows a subclass or child class to redefine a method of superclass or parent class. In this chapter, we will implement the polymorphism using the concept of method overriding.

多态性一词源自极客术语 polymorph。如果你拆分 polymorph,则“poly”的意思是许多,“morph”的意思是从一种状态转换为另一种状态。

The polymorphism word is derived from the geek word polymorph. If you break the polymorph, the meaning of the 'poly' means many, and 'morph' means transforming from one state to another state.

Method Overriding

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

Before you understand the polymorphism, it is important to understand the method overriding.

如果在父类和子类中定义一个具有相同名称的方法,则子类方法会覆盖父类的方法。

If you define a method with the same name in the parent and child class, the child class method overrides the parent class’s method.

例如,你想要计算不同形状的面积。你已经定义了包含 area() 方法的 Shape 类。现在,你为不同的形状有不同的类,并且所有这些类都扩展 Shape 类,但是你不能使用 Shape 类的 area() 方法来找到每个形状的面积,因为每个几何形状都有不同的面积计算公式。

For example, you want to calculate the area of the different shapes. You have defined the Shape class containing the area() method. Now, you have a different class for the different shapes, and all extend the Shape class, but you can’t use the area() method of the Shape class to find the area of each shape as each geometry has a different formula to find the area.

所以,你需要在每个子类中定义 area() 方法,覆盖 Shape 类的 area() 方法,然后找到特定形状的面积。通过这种方式,你可以创建单个方法的多种形式。

So, you need to define the area() method in each child class, override the area() method of the Shape class, and find the area of the particular shape. This way, you can create many forms of the single method.

Examples

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

Let’s understand the polymorphism and method overriding via the example below.

Example 1: Demonstrating Polymorphism in JavaScript

在下面的示例中,Shape 类包含 area() 方法。Circle 和 Rectangle 这两个类都扩展了 Shape 类。此外,area() 方法在 Circle 和 Rectangle 类中均已定义。

In the example below, the Shape class contains the area() method. The Circle and Rectangle, both classes, extend the Shape class. Also, the area() method is defined in the Circle and Rectangle class.

在下面的代码中定义了 3 个 area() 方法,但是调用哪个方法取决于你使用哪个类的实例来调用该方法。

There are 3 area() methods defined in the below code, but which method will invoke it depends on which class’s instance you are using to invoke the 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) { // 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

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

This way, you can define the same method with different functionalities and invoke a particular one according to the required functionalities.

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

You can also call the parent class method in the child class using the super keyword. Let’s understand it via the example below.

Example 2: Parent Class Method’s Functionality Extension in Child Class

Math 和 AdvanceMath 类在下面的示例中包含 mathOperations() 方法。

The Math and AdvanceMath class contains the mathOperations() method in the example below.

在 AdvanceMath 类的 mathOperations() 方法中,我们使用了 super 关键字来调用父类的 mathOperations() 方法。我们在 AdvanceMath 类的 mathOperations() 方法中扩展了 math 类的 mathOperations() 方法的功能。

In the mathOperations() method of the AdvanceMath class, we used the super keyword to invoke the mathOperations() method of the parent class. We extend the functionality of the math class’s mathOperations() method in the AdvanceMath class’s mathOperations() method.

此外,当你使用 Math 类的对象调用 mathOperation() 方法时,它只调用 Math 类的这个方法。

Also, when you invoke the mathOperation() method using the object of the Math class, it invokes the method of the Math class only.

<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 引擎根据使用哪个类的实例来决定在运行时应该执行哪个方法。

This type of polymorphism is called runtime polymorphism, as the JavaScript engine decides which method it should execute at the run time based on which class’s instance is used.

Benefits of using Polymorphism in JavaScript

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

There are many advantages to using polymorphism in JavaScript; we have explained some of them here.

  1. Code reusability − Polymorphism allows you to reuse the code. In the second example, we have reused the code of the mathOperations() method of the math class.

  2. Extensibility − You can easily extend the current code and define new functionalities.

  3. Dynamic behaviors − You can have multiple classes containing the same method with different functionalities and call the method of the particular class dynamically at the run time.