Javascript 简明教程

JavaScript - Inheritance

Inheritance in JavaScript

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

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

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

本章节中使用以下术语。

  1. Parent class − 它是一个属性被其他类继承的类。

  2. Child class − 它是一个继承其他类属性的类。

JavaScript Single Class Inheritance

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

Syntax

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

class childClass extends parentClass {
    // Child class body
}

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

Example: Single Class Inheritance

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

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

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

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

<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

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

JavaScript super() Keyword

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

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

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

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

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

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

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

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

<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

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

JavaScript Multilevel Inheritance

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

Syntax

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

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

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

Example

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

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

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

<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 等级继承中,一个类被多个类继承。

Syntax

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

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

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

Example

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

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

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

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

<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 关键字来调用父类的静态方法。在子类之外,可以使用子类名称来调用父类和子类的静态方法。

Example

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

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

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

<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

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

Syntax

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

Child.prototype = Instance of parent class

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

Example: JavaScript Prototype Based Inheritance

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

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

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

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

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

<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 中继承概念的优势。

  1. Code reusability − 子类可以继承父类的属性。因此,这是重用父类代码的最佳方式。

  2. Functionality extension − 可以在每个子类中添加新属性和方法来扩展父类功能。

  3. Code maintenance − 可以把代码分成子类,这样维护代码会更容易。

  4. 多级和分层继承允许您合并数据。