Polymorphism: The Art of Flexible Forms

What is Polymorphism?

Imagine you have a universal remote control that works differently with various devices. When you press "power":

This is polymorphism in action! The same button (method) produces different but appropriate results based on the context (object type).

The Two Faces of Polymorphism

Method Overloading: The Multi-Tool

Like a Swiss Army knife with different tools in one handle:

class Calculator {
    add(a, b) { return a + b }          // Screwdriver
    add(numbers) { /* sum array */ }    // Scissors
}

Method Overriding: The Custom Upgrade

Like replacing standard car tires with snow tires:

class Vehicle {
    move() { /* basic movement */ }
}

class Snowmobile extends Vehicle {
    move() { /* track-based movement */ }
}

JavaScript's toString() Symphony

All JavaScript objects inherit the toString() method from Object, but each instrument plays it differently:

Array Orchestra

const arr = [1, 2, 3];
console.log(arr.toString()); // "1,2,3"

Date Solo

const now = new Date();
console.log(now.toString()); // "Wed Jul 24 2024 10:30:00 GMT+0000"

Custom Instrument

class Guitar {
    constructor(brand) {
        this.brand = brand;
    }
    
    toString() {
        return `🎸 ${this.brand} Guitar`;
    }
}

console.log(new Guitar('Fender').toString()); // "🎸 Fender Guitar"

The Eraser Factory: Real-World Analogy

Different writing tools erase in unique ways:

class WritingTool {
    erase() {
        throw new Error("Implement erase() in child class!");
    }
}

class Pencil extends WritingTool {
    erase() {
        return "Rubber eraser smudging graphite";
    }
}

class Pen extends WritingTool {
    erase() {
        return "Chemical eraser dissolving ink";
    }
}

class WhiteboardMarker extends WritingTool {
    erase() {
        return "Felt eraser wiping surface clean";
    }
}

🖋️ Real Application: A drawing app could use these classes to handle different erase behaviors without changing the UI code.

When to Use Polymorphism

E-commerce Payment System

class PaymentGateway {
    process(amount) { /* generic processing */ }
}

class CreditCardProcessor extends PaymentGateway {
    process(amount) { /* contact bank */ }
}

class CryptoProcessor extends PaymentGateway {
    process(amount) { /* blockchain magic */ }
}

class PayPalProcessor extends PaymentGateway {
    process(amount) { /* API call to PayPal */ }
}

💡 The checkout system can process payments polymorphically without knowing specific details!

Advanced Concepts to Explore

Duck Typing

"If it quacks like a duck..." JavaScript's dynamic polymorphism

Strategy Pattern

Switching algorithms at runtime through polymorphic objects

Abstract Classes

Template classes that enforce method implementation

Polymorphism in the Wild