深层继承的局限
本课属于 Coddy JavaScript 学习旅程的“面向对象编程”单元。第 48 课,共 56 课。
虽然继承很有用,但创建非常深的继承层级(父类 → 子类 → 孙类 → 曾孙类)可能会带来问题。继承链越深,代码就越难理解、维护和修改。
来看看多层继承链会发生什么:
// 基类
class Vehicle {
constructor(type) {
this.type = type;
this.isRunning = false;
}
start() {
this.isRunning = true;
console.log(`${this.type} started`);
}
}
// 第一层继承
class Car extends Vehicle {
constructor(make, model) {
super("Car");
this.make = make;
this.model = model;
this.wheels = 4;
}
honk() {
console.log("Beep beep!");
}
}
// 第二层继承
class SportsCar extends Car {
constructor(make, model, topSpeed) {
super(make, model);
this.topSpeed = topSpeed;
}
race() {
this.start();
console.log(`Racing at ${this.topSpeed} mph!`);
}
}在这个示例中,SportsCar 的继承层级有两层。这可能会导致一些问题:
- 对 Vehicle 的更改可能会意外地导致 SportsCar 出现问题
- 随着继承链变长,追踪方法和属性的来源会变得更困难
- 你会被迫使用“是一个”关系,而这种关系可能不够灵活
挑战
完成 Robot.js 文件,让机器人能够正常工作。现在机器人已经构建完成,但还什么也做不了。
Robot.js 中要做的事:
- 创建 speaker 和 mover 组件,并将它们放在 Robot 构造函数中
- 在方法中使用这些组件:
- 在
greet()中:调用this.speaker.speak("Hello!"); - 在
walkForward()中:调用this.mover.move("forward");
- 在
这样做的原因:这就是组合,机器人由更小的组件组合而成。机器人拥有一个 speaker(用于说话)和一个 mover(用于移动),而不是通过继承获得这些能力。
亲手试试
import { Robot } from './Robot.js';
const myRobot = new Robot('Robo');
myRobot.greet(); // 应输出:Saying: "Hello!"
myRobot.walkForward(); // 应输出:Moving forward这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
8整理 OOP 代码
将类组织到模块中自己练习: JavaScript 在线编译器