1、类的继承 extends
类可以继承另外一个类。这是一个非常棒的语法,在技术上是它基于原型继承实现的。
为了继承另外一个类,我们需要在括号 {..} 前指定 "extends" 和父类
这里我们写一个继承自 Animal 的 Rabbit:
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed += speed;
alert(`${this.name} runs with speed ${this.speed}.`);
}
stop() {
this.speed = 0;
alert(`${this.name} stopped.`);
}
}
// 从 Animal 继承
class Rabbit extends Animal {
hide() {
alert(`${this.name} hides!`);
}
}
let rabbit = new Rabbit("White Rabbit");
rabbit.run(5); // 白色兔子会以速度 5 奔跑。
rabbit.hide(); // 白色兔子藏了起来!
就如你期望的那样,也正如我们之前所见,extends 关键字实际上是给 Rabbit.prototype 添加了一个属性 [[Prototype]],并且它会指向 Animal.prototype。

所以现在 rabbit 既可以访问它自己的方法,也可以访问 Animal 的方法。
2、extends 后可跟表达式
Class 语法的 `extends' 后接的不限于指定一个类,更可以是表达式。
例如一个生成父类的函数:
function f(phrase) {
return class {
sayHi() { alert(phrase) }
}
}
class User extends f("Hello") {}
new User().sayHi(); // Hello
例子中,class User 继承了 f('Hello')返回的结果。
对于高级编程模式,当我们使用的类是根据许多条件使用函数来生成时,这就很有用。
3、通过继承重写一个方法
现在让我们进入下一步,重写一个方法。到目前为止,Rabbit 从 Animal 继承了 stop 方法,this.speed = 0。
如果我们在 Rabbit 中指定了自己的 stop,那么会被优先使用:
class Rabbit extends Animal {
stop() {
// ...this will be used for rabbit.stop()
}
}
......但通常我们不想完全替代父方法,而是在父方法的基础上调整或扩展其功能。我们进行一些操作,让它之前/之后或在过程中调用父方法。
Class 为此提供 super关键字。
使用 super.method(...) 调用父方法。
使用 super(...) 调用父构造函数(仅在 constructor 函数中)。
例如,让兔子在 stop 时自动隐藏:
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed += speed;
alert(`${this.name} runs with speed ${this.speed}.`);
}
stop() {
this.speed = 0;
alert(`${this.name} stopped.`);
}
}
class Rabbit extends Animal {
hide() {
alert(`${this.name} hides!`);
}
stop() {
super.stop(); // call parent stop
this.hide(); // and then hide
}
}
let rabbit = new Rabbit("White Rabbit");
rabbit.run(5); // White Rabbit runs with speed 5.
rabbit.stop(); // White Rabbit stopped. White rabbit hides!
现在,Rabbit 的 stop 方法通过 super.stop() 调用父类的方法。
网友评论