Question:
What is Polymorphism?
Quick answer:
It is an ability to use objects of different types, providing them the same interface, or use of one entity representing different types.
Longer answer:
As we discussed in previous article about inheritance, it is possible to move shared functionality to the parent class and then extend it in child classes.
But how do we actually work with this shared functionality?
We can just expect that we are always working with an instance of the parent class, but they may be instances of the child classes. It may be intuitive, but it is called subtyping polymorphism.
class Human {
sayHi() {
alert('Hi! ')
}
}
class Child extends Human {
sayHi() {
alert('Hi πΆ')
}
}
class Parent extends Human {
sayHi() {
alert('Hi πββοΈ')
}
}
class GrandParent extends Human {
sayHi() {
alert('Hi π΅')
}
}
// In Typescript:
// function introduce(human: Human) {
function introduce(human) {
human.sayHi()
}
let childObj = new Child()
introduce(childObj);
let parentObj = new Parent()
introduce(parentObj)
let grandParentObj = new GrandParent()
introduce(grandParentObj)
There is also a bit more complex polymorphism example, called parametric polymorphism. It is just generics in Typescript.
class <T>List {
data: T[];
push(elem: T) {}
pop(elem: T) {}
}
Since JavaScript is a dynamically typed language, I don't think there is such thing as parametric polymorphism, but please correct me if I'm wrong.
The last thing we will touch is ad hoc polymorphism. It is when you have one function name, but different types of arguments. As JavaScript is a dynamically typed language, these checks are performed during runtime.
function add(a, b) {
if (Array.isArray(a) && Array.isArray(b)) {
return a.concat(b)
}
if (typeof a === 'number' && typeof b === 'number') {
return a + b
}
if (typeof a === 'string' && typeof b === 'string') {
return a + b
}
throw new Error('Unknown types')
}
add(1,2) // 3
add('abc', 'def') // 'abcdef'
add([1,2], [3,4]) // [1, 2, 3, 4]
Real-life applications:
Basically, the use of polymorphism can open Pandora's box to the world of utils & helpers which only their creator knows how to use.
^^^ That feeling when you understood a few hundreds of lines of code, which checks all cases for all types in one place π€―
Another caveat is to extend parent class in a way that it is no longer replaceable.
class Bird {
fly() {}
}
class Pigeon extends Bird { }
class Penguin extends Bird {
fly() { throw new Error("I can't fly!") }
}
function makeThemFly(birds) {
birds.forEach(bird => bird.fly())
}
makeThemFly([new Pigeon(), new Penguin()]) // This will blow π₯
Resources:
wiki/Polymorphism
w3schools/Polymorphism (Java)
MDN
Other posts:
- JS interview in 2 minutes / Inheritance in OOP
- JS interview in 2 minutes / Object-Oriented Programming (OOP)
- JS interview in 2 minutes / Static vs Dynamic typing
Btw, I will post more fun stuff here and on Twitter. Let's be friends π
Top comments (0)