JavaScript - 继承



JavaScript 中的继承

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

有时,您必须将一个类的属性和方法添加到另一个类中。例如,您已经创建了一个通用的自行车类,其中包含每辆自行车的相同属性和方法。之后,您为“本田”自行车创建一个单独的类,并且需要向“本田”类添加所有属性和方法。您可以使用继承来实现这一点。

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

本章使用以下术语。

  • 父类 - 其属性被其他类继承的类。

  • 子类 - 继承其他类属性的类。

JavaScript 单继承

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

语法

您可以遵循以下语法进行单继承。

class childClass extends parentClass {
    // Child class body
}

在上述语法中,您可以将 'childClass' 替换为子类的名称,将 'parentClass' 替换为父类的名称。(此处应有代码示例,原文缺失)

示例:单继承

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

“Bike”类包含 constructor() 方法,用于初始化 gears 属性,以及 getGears() 方法,用于返回 gears 属性的值。

“Suzuki”类包含 constructor() 方法,用于初始化 brand 属性,以及 getBrand() 方法,用于返回 brand 属性的值。

我们创建了一个“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() 关键字

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

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

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

示例:使用 super() 关键字初始化父类属性

在下面的示例中,“Suzuki”类扩展了“Bike”类。(此处应有代码示例,原文缺失)

“Bike”类包含构造函数,它接受 gears 作为参数,并用它初始化 gears 属性。

“Suzuki”类也包含构造函数,它接受 brand 和 gears 作为参数。它使用 brand 参数初始化 brand 属性,并将 gears 参数作为 super() 关键字的参数传递。

之后,我们创建了一个“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 多层继承

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

语法

用户可以遵循以下语法进行多层继承。(此处应有代码示例,原文缺失)

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

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

示例

在下面的示例中,“Honda”类继承“Bike”类。“Shine”类继承“Honda”类。(此处应有代码示例,原文缺失)

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

我们正在使用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层次继承

在JavaScript层次继承中,一个类被多个类继承。

语法

J的语法您可以按照以下语法进行层次继承。

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

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

示例

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

Honda类扩展了Bike类。Honda类的constructor()方法使用super()关键字初始化Bike类的属性以及自身的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"}

继承类的静态成员

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

示例

在下面的示例中,Bike类包含getDefaultBrand()静态方法。Honda类也包含Bikename()静态方法。

在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
当您在多级继承中使用'super'关键字执行任何方法时,类会在父类中查找方法。如果在父类中找不到该方法,则会在父类的父类中查找,依此类推。

基于JavaScript原型的继承

您还可以更新或扩展类的原型,以将多个类的属性继承到单个类中。因此,这也称为多重继承。

语法

您可以按照以下语法使用基于原型的继承。

Child.prototype = Instance of parent class

在上例语法中,我们将父类实例赋值给子对象的原型。

示例:基于JavaScript原型的继承

在下面的示例中,Bike()是一个对象构造函数,它初始化brand属性。

之后,我们将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
您无法访问子类中父类的私有成员。

继承的优点

在这里,我们将学习JavaScript中继承概念的优点。

  • 代码重用 − 子类可以继承父类的属性。因此,这是重用父类代码的最佳方法。

  • 功能扩展 − 您可以添加新的属性和方法来扩展每个子类中父类的功能。

  • 代码维护 − 因为您可以将代码划分为子类,所以更容易维护代码。

  • 多级和层次继承允许您将数据组合在一起。

广告