Polymorphism is one of the core concepts of Object-Oriented Programming (OOP) in Java. It allows objects to take multiple forms, enabling flexibility and scalability in code. In simple terms, polymorphism allows a single interface to be used for different data types.
The word Polymorphism comes from Greek, meaning “many forms.” In Java, polymorphism allows a method or an object to behave differently based on the context. For example, a parent class reference can point to a child class object and invoke overridden methods dynamically at runtime. This helps in writing code that is more reusable and maintainable.
Advantages of Polymorphism in Java
- Code Reusability: You can use a single interface for multiple implementations.
- Flexibility: You can introduce new functionality without changing existing code.
- Scalability: Polymorphism makes it easy to extend applications.
- Maintainability: Overriding methods keep code organized and readable.
Types of Polymorphism in Java
Polymorphism in Java is mainly of two types:
- Compile-time Polymorphism (Method Overloading)
- Runtime Polymorphism (Method Overriding)
Compile-time Polymorphism (Method Overloading)
Compile-time polymorphism occurs when multiple methods have the same name but different parameters. The compiler determines which method to call based on the method signature.
Example of Method Overloading:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
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 PolymorphismExample { public static void main(String[] args) { MathOperations math = new MathOperations(); System.out.println(math.add(5, 10)); // Calls method with 2 int parameters System.out.println(math.add(5, 10, 15)); // Calls method with 3 int parameters System.out.println(math.add(5.5, 2.5)); // Calls method with 2 double parameters } } |
The compiler decides which method to call based on the number and type of arguments passed. This is why it is also called static binding.
Runtime Polymorphism (Method Overriding)
Runtime polymorphism occurs when a subclass provides a specific implementation of a method that is already defined in its parent class. The method that gets called is determined at runtime, based on the object’s actual type.
Example of Method Overriding:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
class Animal { void makeSound() { System.out.println("Animal makes a sound"); } } class Dog extends Animal { @Override void makeSound() { System.out.println("Dog barks"); } } class Cat extends Animal { @Override void makeSound() { System.out.println("Cat meows"); } } public class PolymorphismExample { public static void main(String[] args) { Animal myAnimal; myAnimal = new Dog(); // Dog reference assigned to Animal type myAnimal.makeSound(); // Output: Dog barks myAnimal = new Cat(); // Cat reference assigned to Animal type myAnimal.makeSound(); // Output: Cat meows } } |
Here, makeSound()
is overridden in Dog
and Cat
. The method that gets executed depends on the actual object type assigned at runtime. This is known as dynamic method dispatch or late binding.
Real-World Example of Polymorphism
Let’s say, you have a payment system in an e-commerce application. A base class Payment
could have a method pay()
, and different payment methods (CreditCard, PayPal, UPI) can have their own implementations.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
class Payment { void pay() { System.out.println("Processing payment..."); } } class CreditCard extends Payment { @Override void pay() { System.out.println("Payment done using Credit Card"); } } class PayPal extends Payment { @Override void pay() { System.out.println("Payment done using PayPal"); } } public class PaymentSystem { public static void main(String[] args) { Payment payment; payment = new CreditCard(); payment.pay(); // Output: Payment done using Credit Card payment = new PayPal(); payment.pay(); // Output: Payment done using PayPal } } |