JavaScript - 继承
你好,未来的JavaScript法师们!今天,我们将踏上一段激动人心的旅程,探索JavaScript中神奇的继承世界。如果你是编程新手,不用担心;我将作为你的友好向导,我们一步一步地探索这个概念。所以,拿起你的虚拟魔杖(键盘),让我们开始吧!
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 摩托车上做轮滑!
Car
和 Motorcycle
都继承自 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中,继承提供了几个优点:
- 代码复用性
- 可扩展性
- 可维护性
- 多态性
下面是这些优点的总结表格:
优点 | 描述 |
---|---|
代码复用性 | 从父类继承属性和方法,减少重复 |
可扩展性 | 容易向现有类添加新特性 |
可维护性 | 父类中的更改自动反映在子类中 |
多态性 | 通过相同的接口使用不同类的对象 |
记住,能力越大,责任越大。明智地使用继承,你的代码会感谢你!
那么,伙计们,以上就是我们对JavaScript继承的探索。我希望这个指南为你照亮了道路。继续练习,保持好奇心,快乐编码!
Credits: Image by storyset