Skip to main content

Polymorphism in Java

  • Polymorphism in Java allows one interface to be used for a general class of actions.

  • The specific action is determined by the exact nature of the situation.

  • The word "polymorphism" means "many forms," and it occurs when we have many classes that are related to each other by inheritance.

  • Polymorphism is one of the core principles of Object-Oriented Programming (OOP) that allows objects to be treated as instances of their parent class rather than their actual class.

  • This enables flexibility and integration of different classes through a common interface.

Types of Polymorphism

  • Compile-time Polymorphism (Static Binding): Achieved by method overloading.

  • Runtime Polymorphism (Dynamic Binding): Achieved by method overriding.

Method Overloading (Compile-time Polymorphism)

  • Method overloading allows a class to have more than one method with the same name, provided their parameter lists are different.

  • It is resolved during compile time.

Example of Method Overloading

 class MathUtils {
// 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) {
MathUtils math = new MathUtils();
System.out.println(math.add(5, 3)); // Outputs 8
System.out.println(math.add(5, 3, 2)); // Outputs 10
System.out.println(math.add(5.5, 3.3)); // Outputs 8.8
}
}

Method Overriding (Runtime Polymorphism)

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

  • It is resolved during runtime.

Example of Method Overriding

 class Animal {
// Method to be overridden
public void sound() {
System.out.println("Animal makes a sound");
}
}

class Dog extends Animal {
// Overriding the sound method
@Override
public void sound() {
System.out.println("Dog barks");
}
}

class Cat extends Animal {
// Overriding the sound method
@Override
public void sound() {
System.out.println("Cat meows");
}
}

public class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal(); // Animal reference and object
Animal myDog = new Dog(); // Animal reference but Dog object
Animal myCat = new Cat(); // Animal reference but Cat object

myAnimal.sound(); // Outputs: Animal makes a sound
myDog.sound(); // Outputs: Dog barks
myCat.sound(); // Outputs: Cat meows
}
}

Explanation:

  • Superclass (Animal): Contains the method sound().

  • Subclass (Dog): Overrides the sound() method to provide its specific implementation.

  • Subclass (Cat): Also overrides the sound() method to provide its specific implementation.

  • Using Polymorphism: The sound() method call is resolved at runtime based on the actual object type (Dog or Cat), not the reference type (Animal).

Advantages of Polymorphism

  • Flexibility: Write more generic and reusable code.

  • Maintainability: Easier to maintain and extend code as new classes can be added with minimal changes to existing code.

  • Interchangeability: Objects can be replaced or interchanged without affecting the overall system behavior.

Polymorphism in Action: Real-world Example

Consider a scenario where we have a base class Employee and derived classes Manager and Developer. Each class will have a method work() that is implemented differently.

 class Employee {
public void work() {
System.out.println("Employee is working");
}
}

class Manager extends Employee {
@Override
public void work() {
System.out.println("Manager is managing the team");
}
}

class Developer extends Employee {
@Override
public void work() {
System.out.println("Developer is writing code");
}
}

public class Main {
public static void main(String[] args) {
Employee emp1 = new Manager();
Employee emp2 = new Developer();

emp1.work(); // Outputs: Manager is managing the team
emp2.work(); // Outputs: Developer is writing code
}
}

Explanation:

  • Superclass (Employee): Contains the method work().

  • Subclass (Manager): Overrides the work() method to provide its specific implementation.

  • Subclass (Developer): Also overrides the work() method to provide its specific implementation.

  • Using Polymorphism: The work() method call is resolved at runtime based on the actual object type (Manager or Developer), not the reference type (Employee).

Summary

  • Polymorphism: The ability of an object to take on many forms, allowing objects of different classes to be treated through the same interface.

  • Compile-time Polymorphism: Achieved by method overloading, resolved at compile time.

  • Runtime Polymorphism: Achieved by method overriding, resolved at runtime.

  • Advantages: Provides flexibility, maintainability, and interchangeability in code.

  • Real-world Example: Demonstrates how polymorphism can be applied to model real-world scenarios effectively.

Understanding polymorphism is crucial for writing flexible and maintainable object-oriented code in Java.