es6 无原生抽象类,但可通过 throw 抛错模拟抽象方法,强制子类重写;子类用相同方法名和参数签名重写实现多态;实例调用时依据原型链动态分发,统一接口、多种行为。

JavaScript ES6 本身没有原生的“抽象类”或“抽象方法”语法,但可以通过约定 + 运行时检查的方式,模拟抽象方法行为,再配合继承与方法重写,实现多态性——即调用同一方法名,不同子类执行各自逻辑。
用 throw 模拟抽象方法
在父类中定义一个方法,不写具体逻辑,而是直接抛出错误,强制子类必须重写它:
class Animal {
constructor(name) {
this.name = name;
}
// 抽象方法:子类必须重写,否则调用时会报错
speak() {
throw new Error(`子类 ${this.constructor.name} 必须实现 speak() 方法`);
}
}
这样,如果直接 new Animal().speak(),就会立即报错;而子类只有显式覆盖 speak(),才能安全调用。
子类继承并重写方法
子类用 相同方法名、相同参数签名 重新定义 speak(),就完成了重写(override),这是多态的核心操作:
class Dog extends Animal {
speak() {
return `${this.name} 汪汪!`;
}
}
class Cat extends Animal {
speak() {
return `${this.name} 喵喵~`;
}
}
- 重写不要改方法名、参数个数或顺序,否则不是多态,而是新增方法
- 可选地在子类方法中用
super.speak()调用父类逻辑(如果父类有基础实现) - 实例调用时,JS 依据
this的实际构造函数(原型链)动态选择执行哪个版本
运行时多态的实际表现
把不同子类实例统一存进数组,遍历调用同名方法,自动触发各自实现:
const pets = [new Dog('旺财'), new Cat('咪咪')];
pets.forEach(pet => console.log(pet.speak()));
// 输出:
// 旺财 汪汪!
// 咪咪 喵喵~
这里没有 if/else 判断类型,也没有 switch,仅靠方法签名一致 + 原型链查找,就实现了“一个接口、多种行为”。
注意点和常见误区
- ES6 不支持方法重载(overload),即不能靠参数类型/个数不同来区分同名方法
- “抽象”只是语义约束,不是语言强制;靠开发者自觉重写 + 错误提示来保障
- TypeScript 才有真正的
abstract class和abstract method编译期检查 - 多态依赖原型链分发,不是静态绑定;所以一定要用
extends继承,且子类方法定义在原型上(类语法中直接写方法即可)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











