什么是多态性?——向五岁小孩解释多态性
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
在面向类的语言中,类本质上是一段组织良好的代码,它充当创建对象的模板或蓝图。父类也可以被“复制”来创建子类。你可以把父类(超类)和子类(子类)想象成现实生活中父母与子女之间的关系。此外,你也可以把它看作是更抽象的概念或对象与更具体的概念或对象之间的关系,就像超集和子集一样。
当一个孩子出生时,父母的特征会被复制到孩子身上。换句话说,孩子会继承父母的行为。这在面向类的编程语言中被称为类继承。让我们来看一些代码示例:
// Abstract Class: An Aircraft
class Aircraft {
constructor(wings = 2, engines = 2, wheels = 3) {
this.wings = wings;
this.engines = engines;
this.wheels = wheels
}
// Start the engine
start() {
console.log(`turning on my ${this.engines} engines!`);
}
// Stand
stand() {
console.log(`standing on my ${this.wheels} tires!`);
}
// Run on the tracks
run() {
console.log(`moving down the runway on my ${this.wheels} tires!`);
}
// Fly in the sky
fly() {
console.log(`soaring the sky on my ${this.wings} wings!`);
}
}
// A Child Class: A Helicopter
class Helicopter extends Aircraft {
constructor(engines, wheels, propellers) {
super(engines, wheels); // call the super class constructor and pass in the engines and wheels parameter
this.propellers = propellers;
}
propel() {
console.log(`spinning my ${this.propellers} propellers!`);
}
lift() {
this.stand();
this.start();
this.propel();
console.log('slowly climbing up thanks to my spinning propellers!');
}
}
// Another Child Class: An Aeroplane
class Aeroplane extends Aircraft {
constructor(wings, engines, wheels, passengers) {
super(engines, wheels); // call the super class constructor and pass in the name parameter
this.passengers = passengers;
},
start() {
console.log(`turning on my ${this.engines} balanced engines!`);
},
takeOff() {
this.stand();
this.start();
this.run();
this.fly();
console.log(`all of the ${this.passengers} passengers are screaming in delight!`);
}
}
我们定义这类Aircraft飞机时,假定它有两个机翼、两个发动机、三个轮子,能够启动发动机、站立、奔跑,也能飞行。但在现实生活中,你不可能制造出一个通用的“飞机”,所以目前它实际上只是一个抽象概念
。因此,我们定义了两种具体的飞机:直升机和固定翼飞机。
它们都继承了飞机的一些通用特征,但又各自根据自身情况对这些特征进行了相应的调整。直升机需要
两个螺旋桨,起飞时需要推进;而飞机通常需要三个发动机,因为它要运载大量乘客。
多态性是指在继承链的不同层级中,两个或多个类都存在相同的属性或方法。它涉及从继承层次结构中更高层的类引用属性或方法。
在大多数面向类的语言(包括 ES6)中class,可以通过在子类的任何方法中调用super()关键字并加上要访问的属性或方法的名称来实现这一点。这样做时,JavaScript 引擎会向上查找父类中的方法。
现在,让我们考虑一下多态性在我们类示例中的一个有趣应用。该方法在父类和子类start()中都定义过。当你在父类和子类中都定义了一个同名方法时,就称为重写了父类的方法。如果你仔细观察,你会发现该方法引用了父类和子类中都存在的 `start()` 方法。你认为 JavaScript 引擎会使用哪个版本的 `start()` 方法?是父类中的版本,还是子类中的版本?HelicopterAeroplanetakeoff()start()AircraftAeroplane
这就引出了关于多态性必须始终牢记的一个关键点:
- 当你在子类中引用任何属性或方法时,引擎首先会检查该方法是否已存在于当前子类中。如果存在,引擎则直接使用该方法。如果不存在,引擎会“查找”下一个(父)类,以此类推。
现在来回答这个问题,JavaScript 引擎将使用Aeroplanes 版本start(),这将解析为 3 个引擎,因为一架客机有 3 个引擎:
const plane = new Aeroplane(2, 3, 3, 117)
console.log(plane.takeOff())
/* turning on my 3 balanced engines!
Standing on my 3 wheels
Moving down the track on my 3 tires
Soaring the sky on my 2 wings
all the 117 passengers are screaming in delight */
如果我们实例化的是泛型类,那么就会调用Aircraft它的相应版本:start()
const aircraft = new Aircraft() // Nothing passed because we had set default parameters
console.log(aircraft.start())
// turning on my two engines!
顾名思义,多态性允许你以多种形式定义和使用属性和方法。在我们的例子中,该start()方法有两种形式,具体使用哪种形式取决于实例化的类。
多态是面向对象编程中一个非常有用的特性。你可以创建一个接口,然后在多个子类中复用。这样可以节省时间,并大大减少代码量。
在 JavaScript 中,谈到多态和继承,有一个重要的行为需要理解:[[Prototype]]机制。它描述了引擎如何向上遍历,查找超类中是否存在某个属性或方法,直到找到原型对象。
其机制是什么[[Prototype]]?我们将在下一期“像给五岁小孩解释一样解释”系列节目中探讨这个问题。
您可能也喜欢:
文章来源:https://dev.to/ubahthebuilder/what-is-polymorphism-explaining-polymorphism-to-a- Five-year-old-12dg附言:如果您喜欢这类文章,请关注本博客,以免错过任何更新。如果您正在学习 JavaScript,那么您绝对应该看看我的JavaScript 笔记。