分類
數字趨勢

什么是多态?以及为什么值得学习

如果您可以驾驶4门通勤车,也可以驾驶皮卡车。如果您驾驶的是带有内燃机的汽车,那么您也可以驾驶电动汽车。

乘用车的形状和大小可能会有所不同。运行这些车辆的电动机也可能完全不同。但这对驾驶员没有关系。

您只需上车,系好安全带,启动车辆,将其挂档并驱动。那是因为汽车,卡车和货车是多态的

多态性:分解

让我们看一下单词多态性。您可以将其分解为polymorphism

多边形意味着很多,就像多边形意味着很多角度一样。当作为名词使用的,变形是一个物种的变体。 ism可以表示系统。

因此,多态只是意味着一个具有多种变体的系统。但是,这仍然不能告诉您很多有关在编程中如何使用它的信息。接下来。

如果它像鸭子一样走…为什么多态对象很棒

当您在代码中创建一个继承自另一个类的类时,会将新类绑定到合同。合同规定,父级中的每个变量和函数也都在子级中。

每辆车都有方向盘,油门和制动踏板以及转向信号灯。您无需打开引擎盖即可开车。重要的是这是一辆汽车。

同样的情况适用于从其他类继承的类。这是TypeScript中的一个示例:

 
class Vehicle {
private _engine: string;
private _tires: number;
constructor(engine: string = "combustion", tires: number = 4) {
this._engine = engine;
this._tires = tires;
}
accelerate(velocity: number) {
console.log("accelerating at a velocity of " + velocity);
}
brake(pressure: number) {
console.log("applying " + pressure + " pressure");
}
turnLeft() {
console.log("turning left");
}
turnRight() {
console.log("turning right");
}
}
class Car extends Vehicle {
}
class Tesla extends Car {
constructor() {
super("electric");
}
}

在此示例中,有一个Vehicle类。 Car类继承自Vehicle类。特斯拉汽车继承而来。现在让我们创建几个对象并对其进行观察。

 let myCoupe: Car = new Vehicle();
console.log(myCoupe);
console.log(myCoupe.constructor.name);
let mySedan: Vehicle = new Tesla();
console.log(mySedan);
console.log(mySedan.constructor.name);
myCoupe.turnLeft();
mySedan.turnLeft();

您可以看到我们宣布myCoupeCar,mySedanVehicle 。然后,我们将myCoupe实例化为新的Vehicle ,将mySedan实例化为新的Tesla 。如果您访问TypeScript沙箱并运行代码,您会发现它可以正常工作而不会出现error 。根据合同,它的行为符合您的预期。

换句话说,所有车辆都可以向左转,因为它们是从Vehicle类继承而来的。编制者知道, Vehicle的每个孩子都同意合同。因此,无论对象被键入或实例化为什么类,它都假设一切都很好。

有时称为“鸭子打字”。编译器假设,如果它走路像鸭子一样说话,像鸭子一样说话,那么它很可能就是鸭子。因此,编译器无需担心细节,而只是将对象视为鸭子。

多态使您的代码防弹

多态契约的另一个优点是可以保证您的代码正常工作。如果您对所有变量以及每个函数返回的值都进行了严格键入,那么您将知道每个子代将始终匹配变量,函数和类型。

这意味着您可以在不破坏程序的情况下添加和更改类中的代码。不管Car进行了多少更改,每个引用Vehicle对象的对象都将始终获得满足期望的数据和功能。

函数内部的代码可能无法输出正确的结果。但这是另一种问题。只要函数遵循协定并返回预期的变量类型,就不会导致代码破坏错误。

多态是巨大的,这里还有十种您应该知道的编程原理

实践多态

  • 使用上面的沙盒链接创建Boat类。
  • 以“车辆”类型实例化新船对象,但仍看起来像船。
  • 确保船的行为仍然像车辆。

多态性的最后一个例子

最初,多态可能是一个棘手的概念。但是一旦掌握了它,您就朝着理解面向对象编程的真正意义迈出了一大步。但是,该概念似乎仍然是理论上的。因此,这是一个真实的示例,可以帮助您了解它的实用性。

想象一下,您正在构建一个连接到MySQL数据库的Web应用程序。然后,老板决定切换到PostgreSQL数据库。这是否意味着您必须重写所有数据库调用?

不,不是。如果您的应用程序使用DataAccess类以及实际上与数据混为一谈的子类,那么您很幸运。 DataAccess类定义您的应用程序如何与数据交互,而不是它如何与数据库交互。

您有像MySQLAccessPostgresQLAccess这样的子类可以完成所有肮脏的工作。但是,如果您的应用程序仅包含DataAccess对象,则可以换出数据库而无需重写任何一行应用程序代码。