LLD Hub
Learn

PolymorphismOne interface, many behaviours

One interface, many implementations — callers stay dumb. · Avoid instanceof chains; dispatch through the interface.

Watch

Watch, then scroll down for code and practice.

In code

Polymorphic paymentTypeScript
interface Payment {
  authorize(amount: number): boolean;
}

class CardPay implements Payment {
  authorize(amount: number) {
    return amount < 10_000;
  }
}

class UpiPay implements Payment {
  authorize() {
    return true;
  }
}

function checkout(p: Payment, amt: number) {
  if (!p.authorize(amt)) throw new Error("declined");
}

📘 Key ideas

Runtime polymorphism

A parent reference holds a child object. The actual method called is determined at runtime — this is dynamic dispatch.

The litmus test

If your code has instanceof checks or type-switch logic, your design is wrong. Good polymorphism means the caller never needs to know the concrete type.

Open for extension

Add new payment methods (Crypto, BNPL) without touching Checkout.processPayment() — just add a new class that implements Payment.

Compile-time polymorphism

Method overloading — same name, different parameter types. Less powerful but sometimes useful for convenience APIs.

🧠 Practice — Apply What You Learned

🚀 Now apply what you learned

Pick a problem above, write your solution, and get AI feedback on your design.

Start Practice →