Polymorphism, a core concept in Object-Oriented Programming (OOP), enables objects of different types to be treated as objects of a common type. It enhances flexibility, extensibility, and the ability to write code that is both concise and robust. Let’s explore the various forms of polymorphism in Java.
1. Compile-Time Polymorphism (Method Overloading):
Compile-time polymorphism, also known as method overloading, occurs when a class has multiple methods with the same name but different parameter lists.
class Calculator {
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
}
In this example, the add
method is overloaded to handle both int
and double
types.
2. Run-Time Polymorphism (Method Overriding):
Run-time polymorphism, achieved through method overriding, allows a subclass to provide a specific implementation for a method that is already defined in its superclass.
class Shape {
void draw() {
System.out.println("Drawing a shape");
}
}
class Circle extends Shape {
@Override
void draw() {
System.out.println("Drawing a circle");
}
}
Here, the draw
method is overridden in the Circle
subclass, providing a specialized implementation.
3. Polymorphism with Interfaces:
Interfaces in Java enable polymorphism by allowing multiple classes to implement the same interface, providing their own unique implementations for the interface methods.
interface Sound {
void makeSound();
}
class Dog implements Sound {
@Override
public void makeSound() {
System.out.println("Dog barks");
}
}
class Cat implements Sound {
@Override
public void makeSound() {
System.out.println("Cat meows");
}
}
Objects of the Dog
and Cat
classes can be treated as Sound
objects, allowing for polymorphic behavior.
4. Polymorphism with Abstract Classes:
Abstract classes can also contribute to polymorphism. Abstract methods in an abstract class are implemented by concrete subclasses.
abstract class Shape {
abstract void draw();
}
class Circle extends Shape {
@Override
void draw() {
System.out.println("Drawing a circle");
}
}
class Square extends Shape {
@Override
void draw() {
System.out.println("Drawing a square");
}
}
Instances of both Circle
and Square
can be treated polymorphically as Shape
objects.
5. Polymorphism in Collections:
Polymorphism is often leveraged in Java collections using interfaces like List
or Map
. For example:
List<Shape> shapes = new ArrayList<>();
shapes.add(new Circle());
shapes.add(new Square());
for (Shape shape : shapes) {
shape.draw(); // Polymorphic behavior
}
Here, different types of shapes can be stored in a List
and processed polymorphically in a loop.
Conclusion:
Polymorphism is a powerful concept that contributes to the elegance and flexibility of Java programs. Whether achieved through method overloading, method overriding, interfaces, or abstract classes, polymorphism allows developers to write code that is adaptable, scalable, and easy to maintain. Embrace polymorphism in your Java projects to create code that is both efficient and extensible. Happy coding!