JavaScript - 继承

你好,未来的JavaScript法师们!今天,我们将踏上一段激动人心的旅程,探索JavaScript中神奇的继承世界。如果你是编程新手,不用担心;我将作为你的友好向导,我们一步一步地探索这个概念。所以,拿起你的虚拟魔杖(键盘),让我们开始吧!

JavaScript - Inheritance

JavaScript中的继承

继承就像是传递家族特征,但在编程世界中。想象你正在创建一个对象的家族树,孩子们可以从父母那里继承属性和方法。酷不酷?

让我们从一个简单的例子开始:

class Animal {
constructor(name) {
this.name = name;
}

speak() {
console.log(`${this.name} 发出声音。`);
}
}

class Dog extends Animal {
bark() {
console.log(`${this.name} 吠叫:汪汪!`);
}
}

const myDog = new Dog("Buddy");
myDog.speak(); // 输出:Buddy 发出声音。
myDog.bark();  // 输出:Buddy 吠叫:汪汪!

在这个例子中,Dog 继承自 Animal。这意味着 Dog 获得了 Animal 的所有属性和方法,加上它自己独特的方法 bark()。就像Buddy从所有动物那里继承了说话的能力,但还有他特别的吠叫超能力!

JavaScript单类继承

单类继承是指一个类只从一个父类继承。这就像有一个超级酷的父母,你想从他们那里学到一切。

这里有一个另一个例子:

class Vehicle {
constructor(brand) {
this.brand = brand;
}

start() {
console.log(`启动 ${this.brand}。`);
}
}

class Car extends Vehicle {
honk() {
console.log(`${this.brand} 车发出哔哔声!`);
}
}

const myCar = new Car("Toyota");
myCar.start(); // 输出:启动 Toyota。
myCar.honk();  // 输出:Toyota 车发出哔哔声!

在这里,Car 继承自 Vehicle。这就像你的车从车辆的一般概念中学到了如何启动,但也知道如何哔哔,因为,嗯,它是辆车!

JavaScript super() 关键字

现在,让我们来谈谈 super() 关键字。它就像是对你的父母表示尊敬的点头,认可他们对你的伟大贡献。

class Animal {
constructor(name) {
this.name = name;
}
}

class Dog extends Animal {
constructor(name, breed) {
super(name); // 调用父类构造器
this.breed = breed;
}

introduce() {
console.log(`我是 ${this.name},一只 ${this.breed} 狗。`);
}
}

const myDog = new Dog("Max", "拉布拉多");
myDog.introduce(); // 输出:我是 Max,一只 拉布拉多 狗。

Dog 构造器中的 super(name) 调用就像是在说:“嘿,动物父母,你能帮我设置名字吗?”这是重用父类构造器逻辑的一种方式。

JavaScript多级继承

多级继承就像是一个有着多代人的家族树。让我们看一个例子:

class Animal {
constructor(name) {
this.name = name;
}

eat() {
console.log(`${this.name} 在吃东西。`);
}
}

class Dog extends Animal {
bark() {
console.log(`${this.name} 叫:汪!`);
}
}

class Labrador extends Dog {
swim() {
console.log(`${this.name} 在游泳。`);
}
}

const myDog = new Labrador("Charlie");
myDog.eat();  // 输出:Charlie 在吃东西。
myDog.bark(); // 输出:Charlie 叫:汪!
myDog.swim(); // 输出:Charlie 在游泳。

在这里,Labrador 继承自 Dog,而 Dog 又继承自 Animal。就像Charlie the Labrador从所有动物那里学会了吃东西,从狗那里学会了叫,还有他自己的特殊游泳能力。

JavaScript分层继承

分层继承是指多个类从单个父类继承。这就像兄弟姐妹从同一个父母那里继承特征。

class Vehicle {
constructor(brand) {
this.brand = brand;
}

start() {
console.log(`启动 ${this.brand}。`);
}
}

class Car extends Vehicle {
drive() {
console.log(`驾驶 ${this.brand} 车辆。`);
}
}

class Motorcycle extends Vehicle {
wheelie() {
console.log(`在 ${this.brand} 摩托车上做轮滑!`);
}
}

const myCar = new Car("Toyota");
const myBike = new Motorcycle("Harley");

myCar.start();    // 输出:启动 Toyota。
myCar.drive();    // 输出:驾驶 Toyota 车辆。

myBike.start();   // 输出:启动 Harley。
myBike.wheelie(); // 输出:在 Harley 摩托车上做轮滑!

CarMotorcycle 都继承自 Vehicle,但他们各自有自己的独特方法。

继承类的静态成员

静态成员属于类本身,而不是实例。但他们仍然可以被继承!让我们看看如何:

class MathOperations {
static PI = 3.14159;

static calculateCircleArea(radius) {
return this.PI * radius * radius;
}
}

class AdvancedMath extends MathOperations {
static calculateSphereVolume(radius) {
return (4/3) * this.PI * radius * radius * radius;
}
}

console.log(AdvancedMath.PI); // 输出:3.14159
console.log(AdvancedMath.calculateCircleArea(5)); // 输出:78.53975
console.log(AdvancedMath.calculateSphereVolume(3)); // 输出:113.09733

在这里,AdvancedMath 继承了静态的 PI 属性和 calculateCircleArea 方法从 MathOperations

JavaScript基于原型的继承

在ES6类出现之前,JavaScript使用基于原型的继承。这有点复杂,但仍然重要的是要理解:

function Animal(name) {
this.name = name;
}

Animal.prototype.speak = function() {
console.log(`${this.name} 发出声音。`);
};

function Dog(name) {
Animal.call(this, name);
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.bark = function() {
console.log(`${this.name} 吠叫:汪汪!`);
};

const myDog = new Dog("Rex");
myDog.speak(); // 输出:Rex 发出声音。
myDog.bark();  // 输出:Rex 吠叫:汪汪!

这实现了和我们的第一个类示例相同的结果,但是使用较老的基于原型的语法。

继承的优点

在JavaScript中,继承提供了几个优点:

  1. 代码复用性
  2. 可扩展性
  3. 可维护性
  4. 多态性

下面是这些优点的总结表格:

优点 描述
代码复用性 从父类继承属性和方法,减少重复
可扩展性 容易向现有类添加新特性
可维护性 父类中的更改自动反映在子类中
多态性 通过相同的接口使用不同类的对象

记住,能力越大,责任越大。明智地使用继承,你的代码会感谢你!

那么,伙计们,以上就是我们对JavaScript继承的探索。我希望这个指南为你照亮了道路。继续练习,保持好奇心,快乐编码!

Credits: Image by storyset