// 定义父类Shape
class Shape {
draw() {
console.log('这是Shape的默认绘制方法');
}
}
// 定义子类Circle
class Circle extends Shape {
draw() {
console.log('绘制圆形');
}
}
// 定义子类Rectangle
class Rectangle extends Shape {
draw() {
console.log('绘制矩形');
}
}
// 多态的体现
// 创建不同子类的实例
const circle = new Circle();
const rectangle = new Rectangle();
// 调用draw方法,根据对象的实际类型调用相应的draw方法
circle.draw(); // 输出: 绘制圆形
rectangle.draw(); // 输出: 绘制矩形
// 在这种情况下,多态通过不同子类对父类方法的重写来体现。虽然它们都继承自同一个父类Shape,
// 但是每个子类都有自己特定的draw方法实现,当通过子类实例调用draw方法时,会执行子类重写后的方法。
// JavaScript引擎确定执行哪个子类的draw方法的过程:
// 1. 首先在实例对象的自身属性中查找draw方法,如果找到则直接执行。
// 2. 如果在实例对象自身没有找到draw方法,JavaScript引擎会沿着原型链向上查找。
// - 对于Circle和Rectangle实例,它们的原型链上首先是各自的构造函数(Circle和Rectangle)的原型对象,
// 这两个原型对象上有各自重写的draw方法,所以会执行子类重写的draw方法。
// - 如果在子类的原型对象上也没有找到draw方法,会继续沿着原型链向上查找,直到找到父类Shape的原型对象上的draw方法(如果还没找到,且原型链已到头,则会抛出TypeError)。