🧠 Java Quiz

Java Polymorphism

"Many forms" — one method call, different behaviors at runtime.

The idea

Polymorphism lets you treat objects of different classes through a common parent type, while each object still uses its own implementation. Calling shape.area() on a list of shapes calls the right method for circles, squares, or triangles — without if-else chains.

Runtime polymorphism (method overriding)

This is the classic OOP polymorphism: subclass overrides a method, and the JVM picks which version to run based on the actual object type.

Shape hierarchy
class Shape {
    public double area() {
        return 0;
    }
}

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

    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
}

class Square extends Shape {
    double side;
    public Square(double s) { this.side = s; }

    @Override
    public double area() {
        return side * side;
    }
}

Now treat any shape uniformly:

Polymorphic call
Shape[] shapes = {
    new Circle(5),
    new Square(4),
    new Circle(3)
};

for (Shape s : shapes) {
    System.out.println(s.area());
    // Each call uses the actual subclass's area() method
}
// 78.539...
// 16.0
// 28.274...

This is sometimes called dynamic dispatch — the JVM resolves which method to call at runtime.

Compile-time polymorphism (method overloading)

Same method name, different parameter lists. The compiler picks which version based on the arguments.

Overloading
class Printer {
    public void print(String s) { System.out.println(s); }
    public void print(int n)    { System.out.println("Number: " + n); }
    public void print(int[] arr) {
        for (int n : arr) System.out.println(n);
    }
}

Upcasting and downcasting

You can assign a subclass object to a superclass variable (upcasting) — that's automatic and safe.

Upcasting
Shape s = new Circle(5);   // Circle treated as Shape
System.out.println(s.area());   // still calls Circle.area()

Downcasting goes the other way and needs an explicit cast plus a runtime check:

Downcasting + instanceof
Shape s = new Circle(5);

if (s instanceof Circle c) {     // Java 16+ pattern
    System.out.println(c.radius);    // safe to access Circle-specific field
}
Why polymorphism matters Without it, you'd write huge if-else chains: if (shape == circle) { ... } else if (shape == square) { ... }. Polymorphism lets you write code that works with whole families of types — the kind of code that scales as your program grows.