Script Valley
Java: Complete Language Course
Object-Oriented Programming in JavaLesson 2.4

Java polymorphism and method overriding at runtime

runtime polymorphism, dynamic dispatch, upcasting, downcasting, instanceof check, abstract classes, abstract methods

Polymorphism

Polymorphism lets you write code against a supertype and have the correct subtype method execute at runtime. This decouples callers from specific implementations and makes code extensible without modification.

Runtime Dispatch

Animal a1 = new Dog("Rex", "Lab");  // upcasting
Animal a2 = new Cat("Luna");

System.out.println(a1.speak()); // Rex barks! — Dog's version
System.out.println(a2.speak()); // Luna meows! — Cat's version

The variable type (Animal) is the compile-time type. The object type (Dog, Cat) is the runtime type. The JVM always dispatches to the runtime type's method when an override exists.

Abstract Classes

public abstract class Shape {
    public abstract double area(); // no body — subclasses must implement

    public void describe() {
        System.out.println("Area: " + area());
    }
}

public class Circle extends Shape {
    private double radius;
    public Circle(double r) { this.radius = r; }

    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
}
Shape s = new Circle(5);
s.describe(); // Area: 78.53...

instanceof checks before downcasting:

if (a1 instanceof Dog d) {   // pattern matching (Java 16+)
    System.out.println(d.getBreed());
}

An abstract class cannot be instantiated directly. It may contain both abstract methods (no body) and concrete methods (with body). Use it when subclasses share meaningful behavior but differ in at least one operation.

Up next

Java interfaces and implementing multiple contracts

Sign in to track progress