# Run-Time Polymorphism and Dynamic Dispatch — Object-Oriented Programming (OOP)

Source: https://www.skillbyai.com/en/oop/p-dynamic

> Explain dynamic dispatch, upcasting, downcasting and instanceof.

## The object decides which method runs

**Run-time** (dynamic) polymorphism happens through **overriding**: a variable declared with a superclass or interface type can refer to objects of many subclasses, and calling a method runs the version of the **actual object's class**, chosen at run time. This is **dynamic dispatch**. In Java all non-static, non-final, non-private instance methods are dispatched dynamically; C++ requires the **`virtual`** keyword (and implements dispatch with a **virtual table**, a per-class table of function pointers). Treating a `Dog` as an `Animal` is **upcasting**, which is always safe and implicit. Converting back, `(Dog) animal`, is **downcasting**, which can fail at run time with `ClassCastException` if the object is not actually a `Dog`; check first with **`instanceof`**, and in modern Java use **pattern matching** (`if (animal instanceof Dog d)`) or `switch` patterns over **sealed** hierarchies. Frequent downcasting is a design smell: it usually means behaviour belongs in an overridden method instead.

## One loop, many behaviours

The declared type is Shape; each object runs its own area().

```java
List<Shape> shapes = List.of(new Circle(1), new Square(2), new Circle(0.5));

double total = 0;
for (Shape s : shapes) {
    total += s.area();          // dynamic dispatch: Circle.area or Square.area
}

Shape s = new Square(3);        // upcasting: implicit and safe
if (s instanceof Square sq) {   // pattern matching (Java 16+)
    System.out.println(sq.perimeter());
}

// sealed hierarchy + switch pattern matching (Java 21+): exhaustive by construction
sealed interface Payment permits Upi, Card, Cash {}
record Upi(String vpa) implements Payment {}
record Card(String last4) implements Payment {}
record Cash() implements Payment {}

static String label(Payment p) {
    return switch (p) {
        case Upi u  -> "UPI " + u.vpa();
        case Card c -> "Card ending " + c.last4();
        case Cash c -> "Cash";
    };
}
```

## A universal remote

Pressing "power" on a universal remote sends the same command to whichever device is connected; the TV, the speaker and the projector each respond in their own way. The remote does not need to know which device it is.

**Quiz:** When is the method body to execute chosen for an overridden method called through a superclass reference in Java?

- [ ] At compile time, from the reference's declared type
- [x] At run time, from the actual object's class
- [ ] When the class is loaded
- [ ] It is chosen randomly

*Answer:* At run time, from the actual object's class. Dynamic dispatch selects the implementation of the object's actual class at run time.
