Introduction
Polymorphism is one of the four fundamental principles of Object-Oriented Programming (OOP) in Java. The term "polymorphism" means "many forms," and it allows objects to be treated as instances of their parent class rather than their actual class. Polymorphism enables one interface to be used for a general class of actions, with the specific action determined by the exact nature of the situation.
Table of Contents
- What is Polymorphism?
- Benefits of Polymorphism
- Types of Polymorphism
- Method Overloading
- Method Overriding
- Real-World Analogy
- Example: Polymorphism in Java
- Conclusion
1. What is Polymorphism?
Polymorphism allows methods to do different things based on the object it is acting upon, even though they share the same name. It enables a single interface to represent different underlying forms (data types). Polymorphism is a powerful feature that allows for flexible and reusable code.
2. Benefits of Polymorphism
- Code Reusability: Polymorphism allows the same method to be used in different ways, reducing code duplication.
- Flexibility: It enables a single interface to represent different data types, making code more flexible and adaptable.
- Maintainability: Polymorphic code is easier to maintain and extend, as changes to a superclass automatically propagate to all its subclasses.
3. Types of Polymorphism
There are two main types of polymorphism in Java:
- Compile-Time Polymorphism (Method Overloading): This type of polymorphism is resolved during compile time.
- Runtime Polymorphism (Method Overriding): This type of polymorphism is resolved during runtime.
4.() Method Overloading
Method overloading is a form of compile-time polymorphism where multiple methods have the same name but different parameters (different type, number, or both).
Example: Method Overloading
public class Calculator { // Method to add two integers public int add(int a, int b) { return a + b; } // Overloaded method to add three integers public int add(int a, int b, int c) { return a + b + c; } // Overloaded method to add two double values public double add(double a, double b) { return a + b; } } public class Main { public static void main(String[] args) { Calculator calculator = new Calculator(); System.out.println("Sum of 2 and 3: " + calculator.add(2, 3)); System.out.println("Sum of 1, 2 and 3: " + calculator.add(1, 2, 3)); System.out.println("Sum of 2.5 and 3.5: " + calculator.add(2.5, 3.5)); } }
Output:
Sum of 2 and 3: 5 Sum of 1, 2 and 3: 6 Sum of 2.5 and 3.5: 6.0
5.() Method Overriding
Method overriding is a form of runtime polymorphism where a subclass provides a specific implementation for a method that is already defined in its superclass. The overridden method in the subclass must have the same signature as the method in the superclass.
Example: Method Overriding
public class Animal { public void sound() { System.out.println("This animal makes a sound."); } } public class Dog extends Animal { @Override public void sound() { System.out.println("The dog barks."); } } public class Cat extends Animal { @Override public void sound() { System.out.println("The cat meows."); } } public class Main { public static void main(String[] args) { Animal myDog = new Dog(); Animal myCat = new Cat(); myDog.sound(); // Calls the overridden method in Dog class myCat.sound(); // Calls the overridden method in Cat class } }
Output:
The dog barks. The cat meows.
6. Real-World Analogy
Consider a vehicle rental system where different types of vehicles (car, bike, truck) are rented. Each vehicle type might have a method rent
with different implementations:
- For a car, the
rent
method might include checking car availability and completing the rental process. - For a bike, the
rent
method might involve checking helmet availability along with the bike. - For a truck, the
rent
method might include additional checks for cargo capacity.
The rent
method behaves differently depending on the vehicle type, but the interface remains consistent.
7. Example: Polymorphism in Java
Let’s create a more detailed example to demonstrate polymorphism in Java.
Example: Polymorphism
// Superclass public class Employee { String name; int employeeId; // Constructor public Employee(String name, int employeeId) { this.name = name; this.employeeId = employeeId; } // Method to display employee details public void displayDetails() { System.out.println("Name: " + name + ", Employee ID: " + employeeId); } } // Subclass 1 public class Manager extends Employee { String department; // Constructor public Manager(String name, int employeeId, String department) { super(name, employeeId); // Call to superclass constructor this.department = department; } @Override public void displayDetails() { super.displayDetails(); // Call to superclass method System.out.println("Department: " + department); } } // Subclass 2 public class Developer extends Employee { String programmingLanguage; // Constructor public Developer(String name, int employeeId, String programmingLanguage) { super(name, employeeId); // Call to superclass constructor this.programmingLanguage = programmingLanguage; } @Override public void displayDetails() { super.displayDetails(); // Call to superclass method System.out.println("Programming Language: " + programmingLanguage); } } public class Main { public static void main(String[] args) { Employee manager = new Manager("Alice", 101, "HR"); Employee developer = new Developer("Bob", 102, "Java"); manager.displayDetails(); developer.displayDetails(); } }
Output:
Name: Alice, Employee ID: 101 Department: HR Name: Bob, Employee ID: 102 Programming Language: Java
In this example, Manager
and Developer
are subclasses of Employee
. Both subclasses override the displayDetails
method to provide specific details. Polymorphism allows us to treat manager
and developer
objects as Employee
objects and call the displayDetails
method, which behaves differently based on the actual object type.
8. Conclusion
Polymorphism in Java allows methods to do different things based on the object it is acting upon. It enables a single interface to represent different underlying forms, promoting code reusability, flexibility, and maintainability. By understanding and implementing polymorphism through method overloading and method overriding, you can create more modular, adaptable, and efficient Java applications.