Polymorphism in Java

What is Polymorphism?

Polymorphism in Java allows a single **interface to be used for multiple forms**. It enables flexibility and scalability in object-oriented programming.

Types of Polymorphism

  • Compile-time (Static) Polymorphism: Achieved using **method overloading**.
  • Runtime (Dynamic) Polymorphism: Achieved using **method overriding**.

1. Method Overloading (Compile-time Polymorphism)

Method Overloading allows multiple methods with the **same name but different parameters**.

class MathOperations {
    // Method with two int parameters
    int add(int a, int b) {
        return a + b;
    }

    // Method with three int parameters
    int add(int a, int b, int c) {
        return a + b + c;
    }

    // Method with double parameters
    double add(double a, double b) {
        return a + b;
    }
}

public class OverloadingExample {
    public static void main(String[] args) {
        MathOperations obj = new MathOperations();
        System.out.println(obj.add(5, 10));       // Calls method with two int parameters
        System.out.println(obj.add(5, 10, 15));   // Calls method with three int parameters
        System.out.println(obj.add(5.5, 2.2));    // Calls method with double parameters
    }
}

2. Method Overriding (Runtime Polymorphism)

Method Overriding allows a **subclass to provide a specific implementation** of a method that is already defined in its superclass.

class Animal {
    void makeSound() {
        System.out.println("Animal makes a sound.");
    }
}

// Dog class overrides makeSound() method
class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Dog barks.");
    }
}

public class OverridingExample {
    public static void main(String[] args) {
        Animal myAnimal = new Dog(); // Runtime polymorphism
        myAnimal.makeSound(); // Calls the overridden method
    }
}

Difference Between Method Overloading & Overriding

Feature Method Overloading Method Overriding
Definition Same method name but different parameters. Same method name and parameters in parent and child class.
Binding Time Compile-time (Static binding) Runtime (Dynamic binding)
Return Type Can have different return types Must have the same return type (or covariant return type)
Usage To increase readability of the code To provide a specific implementation of a method

Real-World Example of Polymorphism

Imagine a **payment system** where different payment methods (CreditCard, PayPal, UPI) have different implementations but use the same **processPayment()** method.

abstract class Payment {
    abstract void processPayment(double amount);
}

// CreditCard class overriding processPayment
class CreditCard extends Payment {
    @Override
    void processPayment(double amount) {
        System.out.println("Processing Credit Card payment of $" + amount);
    }
}

// PayPal class overriding processPayment
class PayPal extends Payment {
    @Override
    void processPayment(double amount) {
        System.out.println("Processing PayPal payment of $" + amount);
    }
}

public class PaymentSystem {
    public static void main(String[] args) {
        Payment payment1 = new CreditCard();
        payment1.processPayment(100.50);

        Payment payment2 = new PayPal();
        payment2.processPayment(75.00);
    }
}

Conclusion

Polymorphism in Java provides **flexibility, scalability, and code reusability**. It allows methods to take **different forms** based on the context.

📌 Next Topic: Abstraction in Java