Javascript 简明教程

JavaScript - Inheritance

Inheritance in JavaScript

inheritance 在 JavaScript 中的概念允许子类继承父类的属性和方法。继承也是面向对象编程的一个基本概念,例如封装和多态。

The concept of inheritance in JavaScript allows the child class to inherit the properties and methods of the parent class. Inheritance is also a fundamental concept of object-oriented programming like encapsulation and polymorphism.

有时,你必须将一个类的属性和方法添加到另一个类中。例如,你已经为自行车创建了一个包含每个自行车相同属性和方法的常规类。然后,你为自行车“本田”创建了一个单独的类,你需要将所有属性和方法添加到“本田”类。你可以使用继承来实现它。

Sometimes, you must add the properties and methods of the one class into another. For example, you have created a general class for the bike containing the same properties and methods for each bike. After that, you create a separate class for the bike "Honda", and you need to add all properties and methods to the "Honda" class. You can achieve it using inheritance.

在 ECMAScript 6 (ES6) 之前,对象的原型用于继承,但是在 ES6 中,引入了“extends”关键字来继承类。

Before ECMAScript 6 (ES6), the object’s prototype was used for inheritance, but in ES6, the 'extends' keyword was introduced to inherit classes.

本章节中使用以下术语。

The following terminologies are used in this chapter.

  1. Parent class − It is a class whose properties are inherited by other classes.

  2. Child class − It is a class that inherits the properties of the other class.

JavaScript Single Class Inheritance

你可以使用“ extends ”关键字将父类属性继承到子类中。在单类继承中,只有一个类继承了另一个类的属性。

You can use the 'extends' keyword to inherit the parent class properties into the child class. In single class inheritance only a single class inherits the properties of another class.

Syntax

你可以按照以下语法进行单类继承。

You can follow the syntax below for the single-class inheritance.

class childClass extends parentClass {
    // Child class body
}

在以上语法中,你可以用子类的名称替换“childClass”,用父类的名称替换“parentClass”。

In the above syntax, you can replace the 'childClass' with the name of the child class and 'parentClass' with the name of the parent class.

Example: Single Class Inheritance

在以下示例中,“Bike”类是一个父类,“Suzuki”类是一个子类。suzuki 类继承了 Bike 类的属性。

In the example below, the 'Bike' class is a parent class, and the 'Suzuki' class is a child class. The suzuki class inherits the properties of the Bike class.

Bike 类包含一个初始化齿轮属性的构造函数 () 方法,以及一个返回齿轮属性值的 getGears() 方法。

The Bike class contains the constructor() method initializing the gears property and the getGears() method returning the value of the gears property.

suzuki 类包含一个初始化品牌属性的构造函数 () 方法,以及一个返回品牌属性值的 getBrand() 方法。

The suzuki class contains the constructor() method to initialize the brand property and getBrand() method, returning the value of the brand property.

我们创建了一个“suzuki”类的对象。使用“suzuki”类实例,我们调用 getBrand() 和 getGears() 方法。

We have created an object of the 'suzuki' class. Using the 'suzuki' class instance, we invoke the getBrand() and getGears() methods.

<html>
<body>
   <div id = "output1">The brand of the bike is: </div>
   <div id = "output2">Total gears in the bike is: </div>
   <script>
      // Parent class
      class Bike {
         constructor() {
            this.gear = 5;
         }

         getGears() {
            return this.gear;
         }
      }
      // Child class
      class suzuki extends Bike {
         constructor() {
            super();
            this.brand = "Yamaha"
         }

         getBrand() {
            return this.brand;
         }
      }

      const suzukiBike = new suzuki();
      document.getElementById("output1").innerHTML += suzukiBike.getBrand();
      document.getElementById("output2").innerHTML += suzukiBike.getGears();
   </script>
</body>
</html>
The brand of the bike is: Yamaha
Total gears in the bike is: 5

通过这种方式,你可以通过子类的实例使用父类的属性和方法。

In this way, you can use the properties and methods of the parent class through the instance of the child class.

JavaScript super() Keyword

在以上示例中,我们使用静态值初始化了 Bike 类的“gear”属性。在现实生活中,你需要根据自行车的型号使用动态值初始化它。

In the above example, we have initialized the 'gear' property of the Bike class with a static value. In real life, you need to initialize it with the dynamic value according to the model of the bike.

现在,问题是如何从子类中初始化父类的属性。解决方案是 super() 关键字。

Now, the question is how to initialize the properties of the parent class from the child class. The solution is a super() keyword.

super() 关键字用于在子类中调用方法或访问父类属性。默认情况下,super() 关键字调用父类的构造函数。你还可以将参数传递给 super() 关键字,以将其传递给父类的构造函数。

The super() keyword is used to invoke the method or access the properties of the parent class in the child class. By default, the super() keyword invokes the constructor function of the parent class. You can also pass the parameters to the super() keyword to pass it to the constructor of the parent class.

Example: Using super() keyword to initialize the parent class properties

在下面的示例中,suzuki 类扩展了 Bike 类。

In the example below, suzuki class extends the Bike class.

Bike 类包含一个构造函数,使用齿轮(gears)作为参数并使用它来初始化齿轮(gears)属性。

The Bike class contains the constructor, taking gears as parameters and, using it, initializes the gears property.

“suzuki” 类也包含一个构造函数,使用品牌(brand)和齿轮(gears)作为参数。使用品牌(brand)参数,它初始化品牌(brand)属性,并使用 super() 关键字的参数形式将齿轮(gears)参数传递进去。

The 'suzuki' class also contains the constructor, taking a brand and gears as a parameter. Using the brand parameter, it initializes the brand property and passes the gears parameter as an argument of the super() keyword.

然后,我们创建一个 “suzuki” 类的对象,并使用品牌(brand)和齿轮(gears)作为构造函数的参数。你可以在输出中看到品牌(brand)和齿轮(gear)属性的动态值。

After that, we create an object of the 'suzuki' class and pass the brand and gears as an argument of the constructor. You can see the dynamic value of the brand and gear property in the output.

<html>
<body>
   <div id = "output1">The brand of the bike is: </div>
   <div id = "output2">Total gears in the bike is: </div>
   <script>
      // Parent class
      class Bike {
         constructor(gears) {
            this.gears = gears;
        }
      }
      // Child class
      class suzuki extends Bike {
         constructor(brand, gears) {
            super(gears);
            this.brand = brand;
         }
      }
      const suzukiBike = new suzuki("Suzuki", 4);
      document.getElementById("output1").innerHTML += suzukiBike.brand;
      document.getElementById("output2").innerHTML += suzukiBike.gears;

   </script>
</body>
</html>
The brand of the bike is: Suzuki
Total gears in the bike is: 4

通过这种方法,你可以从子类动态地初始化父类的属性。

In this way, you can dynamically initialize the properties of the parent class from the child class.

JavaScript Multilevel Inheritance

多层继承是 JavaScript 中的一种继承类型。在多层继承中,一个类继承另一个类的属性,其他类继承当前类的属性。

Multilevel inheritance is a type of inheritance in JavaScript. In multilevel inheritance, one class inherits the properties of another class, and other classes inherit current class properties.

Syntax

用户可以遵循以下语法进行多层继承。

Users can follow the syntax below for the multilevel inheritance.

class A {
}
class B extends A {
}
class C extends B {
}

在上述语法中,C 类继承 B 类,而 B 类继承 A 类。

In the above syntax, the C class inherits the B class, and the B class inherits the A class.

Example

在下面的示例中,Honda 类继承 Bike 类。Shine 类继承 Honda 类。

In the example below, the Honda class inherits the Bike class. The Shine class inherits the Honda class.

我们在每个类中使用 super() 关键字来调用父类的构造函数 () 并初始化其属性。

We use the super() keyword in each class to invoke the parent class’s constructor () and initialize its properties.

我们正在使用 Shine 类的实例访问 Bike 类的属性,因为它间接继承了 Bike 类的属性。

We are accessing the properties of the Bike class using the instance of the Shine class, as it indirectly inherits the properties of the Bike class.

<html>
<body>
   <p id = "output"> </p>
   <script>
      // Parent class
      class Bike {
         constructor(gears) {
            this.gears = gears;
         }
      }
      // Child class
      class Honda extends Bike {
         constructor(brand, gears) {
            super(gears);
            this.brand = brand;
         }
      }
      class Shine extends Honda {
         constructor(model, brand, gears) {
            super(brand, gears);
            this.model = model;
         }
      }
      const newBike = new Shine("Shine", "Honda", 5);
      document.getElementById("output").innerHTML = `The ${newBike.model} model of the ${newBike.brand} brand has total ${newBike.gears} gears.`;
   </script>
</body>
</html>
The Shine model of the Honda brand has total 5 gears.

JavaScript Hierarchical Inheritance

在 JavaScript 等级继承中,一个类被多个类继承。

In JavaScript hierarchical inheritance, one class is inherited by multiple classes.

Syntax

J 的语法你可以遵循以下语法进行等级继承。

The syntax of JYou can follow the syntax below for the hierarchical inheritance.

class A {
}
class B extends A {
}
Class C extends A {
}

在上述语法中,B 和 C 两个类都继承了 A 类的属性。

In the above syntax, B and C both classes inherit the properties of the A class.

Example

在下面的示例中,Bike 类包含齿轮(gears)属性,并使用 constructor() 方法进行初始化。

In the example below, the Bike class contains the gears property and is initialized using the constructor() method.

Honda 类扩展了 Bike 类。Honda 类的 constructor() 方法使用 Bike 类的 super() 关键字和自身的型号(model)属性,对其属性进行初始化。

The Honda class extends the Bike class. The constructor() method of the Honda class initializes the properties of the Bike class using the super() keyword and model property of itself.

Suzuki 类继承 Bike 类属性。Suzuki 类的 constructor() 方法也初始化 Bike 类的属性和自身的其他两个属性。

The Suzuki class inherits the Bike class properties. The constructor() method of the Suzuki class also initializes the Bike class properties and the other two properties of itself.

然后,我们创建了 Honda 和 Suzuki 类对象并访问其属性。

After that, we create objects of both Honda and Suzuki classes and access their properties.

<html>
<body>
   <p id = "output1"> Honda Bike Object: </p>
   <p id = "output2"> Suzuki Bike Object: </p>
   <script>
      // Parent class
      class Bike {
         constructor(gears) {
            this.gears = gears;
         }
      }
      // Child class
      class Honda extends Bike {
         constructor(model, gears) {
            super(gears);
            this.model = model;
         }
      }
      // Child class
      class Suzuki extends Bike {
         constructor(model, color, gears) {
            super(gears);
            this.model = model;
            this.color = color;
         }
      }
      const h_Bike = new Honda("Shine", 5);
      const s_Bike = new Suzuki("Zx6", "Blue", 6);
      document.getElementById("output1").innerHTML += JSON.stringify(h_Bike);
      document.getElementById("output2").innerHTML += JSON.stringify(s_Bike);
   </script>
</body>
</html>
Honda Bike Object: {"gears":5,"model":"Shine"}

Suzuki Bike Object: {"gears":6,"model":"Zx6","color":"Blue"}

Inheriting Static Members of the Class

在 JavaScript 中,你可以使用子类中的 super 关键字来调用父类的静态方法。在子类之外,可以使用子类名称来调用父类和子类的静态方法。

In JavaScript, you can invoke the static methods of the parent class using the super keyword in the child class. Outside the child class, you can use the child class name to invoke the static methods of the parent and child class.

Example

在下示例中,Bike 类包含 getDefaultBrand() static 方法。Honda 类还包含 Bikename() static 方法。

In the example below, the Bike class contains the getDefaultBrand() static method. The Honda class also contains the Bikename() static method.

在 Bikename() 方法中,使用 'super' 关键字调用父类的 getDefaultBrand() 方法。

In the Bikename() method, we invoke the getDefaultBrand() method of the parent class using the 'super' keyword.

另外,我们使用 'Honda' 类名执行 Bikename() 方法。

Also, we execute the Bikename() method using the 'Honda' class name.

<html>
<body>
   <p id = "output">The bike name is: </p>
   <script>
      // Parent class
      class Bike {
         constructor(gears) {
            this.gears = gears;
         }

         static getDefaultBrand() {
            return "Yamaha";
         }
      }
      // Child class
      class Honda extends Bike {
         constructor(model, gears) {
            super(gears);
            this.model = model;
         }
         static BikeName() {
            return super.getDefaultBrand() + ", X6";
         }
      }
      document.getElementById("output").innerHTML += Honda.BikeName();
   </script>
</body>
</html>
The bike name is: Yamaha, X6

JavaScript Prototype Based Inheritance

也可以更新或扩展类的原型以继承多个类对单个类的属性。这样,也称为多重继承。

You can also update or extend the prototype of the class to inherit the properties of the multiple classes to the single class. So, it is also called multiple inheritance.

Syntax

可以采用以下语法使用基于原型的继承。

You can follow the syntax below to use prototype-based inheritance.

Child.prototype = Instance of parent class

在前述语法中,我们把父类的实例分配给子对象的原型。

In the above syntax, we assign the parent class instance to the child object’s prototype.

Example: JavaScript Prototype Based Inheritance

在下示例中,Bike() 是对象构造函数,初始化品牌属性。

In the example below, Bike() is an object constructor that initializes the brand property.

之后,我们把 getBrand() 方法添加到 Bike() 函数的原型中。

After that, we add the getBrand() method to the prototype of the Bike() function.

下一步,我们创建了 Vehicle() 对象构造函数和 Bike() 构造函数的实例。

Next, we have created the Vehicle() object constructor and instance of the Bike() constructor.

之后,使用 Bike 的实例更新 Vehicle 类的原型。这里,Vehicle 作为子类,而 Bike 作为父类。

After that, we update the prototype of the Vehicle class with an instance of the Bike. Here, Vehicle works as a child class and Bike as a parent class.

使用 Vehicle() 函数的实例访问 Bike() 函数的 getBrand() 方法的原型。

We access the getBrand() method of the Bike() function’s prototype using the instance of the Vehicle () function.

<html>
<body>
   <p id = "output1">Bike brand: </p>
   <p id = "output2">Bike Price: </p>
   <script>
      function Bike(brand) {
         this.brand = brand;
      }
      Bike.prototype.getBrand = function () {
         return this.brand;
       }
      //Another constructor function
      function Vehicle(price) {
         this.price = price;
      }
      const newBike = new Bike("Yamaha");
      Vehicle.prototype = newBike; //Now Bike treats as a parent of Vehicle.
      const vehicle = new Vehicle(100000);

      document.getElementById("output1").innerHTML += vehicle.getBrand();
      document.getElementById("output2").innerHTML += vehicle.price;
   </script>
</body>
</html>
Bike brand: Yamaha

Bike Price: 100000

Benefits of Inheritance

这里,我们将了解 JavaScript 中继承概念的优势。

Here, we will learn the benefits of the inheritance concept in JavaScript.

  1. Code reusability − The child class can inherit the properties of the parent class. So, it is the best way to reuse the parent class code.

  2. Functionality extension − You can add new properties and methods to extend the parent class functionality in each child class.

  3. Code maintenance − It is easier to maintain a code as you can divide the code into sub-classes.

  4. Multilevel and hierarchical inheritance allows you to combine data together.