If you can drive a 4-door commuter car, you can also drive a pickup truck. If you’ve driven a car with a combustion motor, you can also drive an electric car.

The shape and size of passenger vehicles may be different from one to the next. The motor that runs those vehicles could be completely different as well. But it doesn’t matter to the driver.

You just get in, buckle up, start the vehicle, put it in gear, and drive. That’s because cars, trucks, and vans are polymorphic.

Polymorphism: Breaking it Down

Let’s look at the word polymorphism. You can break it down into poly, morph, and ism.

Poly means many, like how polygon means many angles. When used as a noun, a morph is a variant of a species. And ism can mean system.

So polymorphism simply means a system of many variations. That still doesn’t tell you much about how it’s used in programming, though. That’s next.

If It Walks Like a Duck… Why Polymorphic Objects Are Awesome

a collection of baby ducks

When you create a class in your code that inherits from another class, you’re binding the new class to a contract. The contract states that every variable and function in the parent will also be in the child.

Every vehicle has a steering wheel, gas and brake pedals, and a turn signal. You don’t need to open the hood to drive a car. All that matters is that it’s a car.

The same thing applies to classes that inherit from other classes. Here is an example in 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");
}
}

In this example, there is a Vehicle class. The Car class inherits from the Vehicle class. And Tesla inherits from Car. Now let’s create a couple of objects and look at them.

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();

You can see that we declared myCoupe to be a Car and mySedan to be a Vehicle. Then we instantiated myCoupe as a new Vehicle and mySedan as a new Tesla. If you visit the TypeScript sandbox and run the code, you’ll see that it works without error. And it behaves as you would expect, based on the contract.

In other words, all vehicles can turn left because they inherited it from the Vehicle class. The compiler knows that every child of Vehicle agreed to the contract. So it assumes all is well, no matter what classes the objects were typed or instantiated as.

This is sometimes called “duck typing.” The compiler assumes that if it walks like a duck and talks like a duck, it might as well be a duck. So the compiler doesn’t worry about the details and just treats the object like a duck.

Polymorphism Makes Your Code Bulletproof

Another advantage of the polymorphism contract is a guarantee that your code will work. If you’ve strongly typed all your variables and what each function returns, you know that every child will always match variables, functions, and types.

That means you can add to and change the code in your classes without breaking your program. Every object that references a Vehicle object will always get data and functionality that meets expectations, no matter how much Car changes.

The code inside the function may not put out the correct results. But that’s a different kind of problem. As long as the function follows the contract and returns the expected type of variable, it won’t result in a code-breaking error.

Polymorphism is huge, and here are 10 more programming principles you should know.

Practice Polymorphism

a bird's eye view of a jetski making a U-turn in very blue water

  • Use the sandbox link above to create a Boat class.
  • Instantiate a new boat object in such a way that it’s a Vehicle type, but still looks like a boat.
  • Make sure that the boat still behaves like a vehicle.

One Final Example of Polymorphism

Polymorphism can be a tricky concept to grasp initially. But once you get it, you’ve taken a huge step towards understanding what object-oriented programming is really all about. The concept may still seem theoretical, though. So here’s a solid real-world example to help you see how useful it is.

Imagine that you’re building a web app that connects to a MySQL database. Then the boss decides to switch to a PostgreSQL database. Does that mean that you have to rewrite all of your database calls?

No, it doesn’t. If your app uses a DataAccess class with sub-classes that actually muck around with the data, you’re in luck. The DataAccess class defines how your app interacts with data, not how it interacts with the database.

You have sub-classes like MySQLAccess and PostgresQLAccess that do all the dirty work. But if your app only has DataAccess objects, you can swap out databases without rewriting a single line of app code.


About The Author

.





Original Content

Website Source

LEAVE A REPLY

Please enter your comment!
Please enter your name here