Object-Oriented Programming

Java Polymorphism

Understand polymorphism in Java — method overloading (compile-time) and method overriding (runtime) with practical examples.

What is Polymorphism?

Polymorphism means "many forms." In Java, it allows objects to behave differently based on their type, even when accessed through a common interface.

There are two types:

TypeMechanismWhen Resolved
Compile-timeMethod OverloadingAt compilation
RuntimeMethod OverridingAt execution

Compile-Time Polymorphism (Method Overloading)

Same method name, different parameters:

java
public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }

    public double add(double a, double b) {
        return a + b;
    }

    public int add(int a, int b, int c) {
        return a + b + c;
    }

    public static void main(String[] args) {
        Calculator calc = new Calculator();
        System.out.println(calc.add(5, 3));         // 8
        System.out.println(calc.add(2.5, 3.7));     // 6.2
        System.out.println(calc.add(1, 2, 3));      // 6
    }
}

Runtime Polymorphism (Method Overriding)

A parent reference can point to a child object. The actual method called depends on the object's type at runtime:

java
public class Animal {
    public void sound() {
        System.out.println("Some generic sound");
    }
}

public class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("Woof! Woof!");
    }
}

public class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("Meow!");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myAnimal;

        myAnimal = new Dog();
        myAnimal.sound();  // Woof! Woof! (Dog's version)

        myAnimal = new Cat();
        myAnimal.sound();  // Meow! (Cat's version)
    }
}

Polymorphism with Arrays

java
Animal[] animals = {
    new Dog(),
    new Cat(),
    new Dog(),
    new Cat()
};

for (Animal a : animals) {
    a.sound();  // Calls the correct overridden method
}

The instanceof Operator

Check the actual type of an object:

java
Animal a = new Dog();

if (a instanceof Dog) {
    System.out.println("It's a dog!");
    Dog d = (Dog) a;  // Downcasting
}

Practical Example: Payment System

java
public abstract class Payment {
    double amount;

    public Payment(double amount) {
        this.amount = amount;
    }

    public abstract void process();
}

public class CreditCardPayment extends Payment {
    public CreditCardPayment(double amount) { super(amount); }

    @Override
    public void process() {
        System.out.printf("Processing credit card payment of ₹%.2f%n", amount);
    }
}

public class UPIPayment extends Payment {
    public UPIPayment(double amount) { super(amount); }

    @Override
    public void process() {
        System.out.printf("Processing UPI payment of ₹%.2f%n", amount);
    }
}

public class Main {
    public static void main(String[] args) {
        Payment[] payments = {
            new CreditCardPayment(5000),
            new UPIPayment(2500),
            new CreditCardPayment(10000)
        };

        for (Payment p : payments) {
            p.process();  // Polymorphic call
        }
    }
}

Summary

  • Polymorphism allows objects to take many forms
  • Compile-time polymorphism: method overloading (same name, different params)
  • Runtime polymorphism: method overriding (parent reference, child object)
  • A parent reference can hold a child object — the overridden method is called
  • Use instanceof to check and safely cast object types
  • Polymorphism is essential for writing flexible, extensible code