Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

Java Polymorphism

What is Polymorphism?

Polymorphism means "many forms." In Java, the same method name can behave differently depending on the context. There are two types:

TypeAlso CalledResolved AtMechanism
Compile-time polymorphismStatic bindingCompile timeMethod overloading
Runtime polymorphismDynamic bindingRuntimeMethod overriding + upcasting

Compile-time Polymorphism (Overloading)

Method Overloading (Compile-time)
public class Overloading {

    // Same method name, different parameter types/count
    public static void print(int n) {
        System.out.println("int: " + n);
    }

    public static void print(double d) {
        System.out.println("double: " + d);
    }

    public static void print(String s) {
        System.out.println("String: " + s);
    }

    public static void print(int a, int b) {
        System.out.println("two ints: " + a + ", " + b);
    }

    public static void main(String[] args) {
        print(42);          // int: 42
        print(3.14);        // double: 3.14
        print("Hello");     // String: Hello
        print(1, 2);        // two ints: 1, 2
        // The compiler picks the right version at compile time
    }
}

Runtime Polymorphism (Dynamic Dispatch)

When a parent-type reference holds a child object (upcasting), the JVM decides at runtime which overridden method to call. This is called dynamic method dispatch.

Runtime Polymorphism & instanceof
class Shape {
    public void draw() {
        System.out.println("Drawing a shape.");
    }
}

class Circle extends Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a circle.");
    }
}

class Rectangle extends Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a rectangle.");
    }
}

class Triangle extends Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a triangle.");
    }
}

public class RuntimePoly {
    public static void main(String[] args) {
        // Upcasting — parent reference, child object
        Shape s1 = new Circle();
        Shape s2 = new Rectangle();
        Shape s3 = new Triangle();

        // JVM calls the correct overridden method at runtime
        s1.draw();  // Drawing a circle.
        s2.draw();  // Drawing a rectangle.
        s3.draw();  // Drawing a triangle.

        // Polymorphic array
        Shape[] shapes = { new Circle(), new Rectangle(), new Triangle() };
        for (Shape s : shapes) {
            s.draw();  // dynamic dispatch

            // instanceof check before downcasting
            if (s instanceof Circle c) {
                System.out.println("  -> This is a Circle");
            }
        }
    }
}

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.