Object-Oriented Programming (OOP) – Polymorphism
Introduction
Polymorphism is a core concept in object-oriented programming (OOP) that allows objects of different classes to be treated as objects of a common superclass. It promotes flexibility and modularity in code, enabling you to write more generic and reusable programs. In this guide, we’ll explore the concept of polymorphism in Java and how it’s achieved through method overriding and interfaces.
Types of Polymorphism
Polymorphism in Java can be categorized into two main types:
- Compile-Time Polymorphism (Static Binding): This is achieved through method overloading, where multiple methods in the same class have the same name but different parameters. The compiler determines the appropriate method to call based on the method’s signature.
- Run-Time Polymorphism (Dynamic Binding): This is achieved through method overriding and interfaces. The decision of which method to call is made at runtime, based on the actual object’s type.
Method Overriding and Dynamic Polymorphism
Dynamic polymorphism is primarily achieved through method overriding. In method overriding, a subclass provides a specific implementation of a method that is already defined in its superclass. The overridden method has the same name, return type, and parameters.
class Shape {
void draw() {
System.out.println("Drawing a shape");
}
}
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");
}
}
In this example, the ‘Circle’ and ‘Square’ classes override the ‘draw’ method from the ‘Shape’ class to provide their specific implementations. The decision of which ‘draw’ method to call depends on the actual object type.
Polymorphism in Action
Polymorphism allows you to write code that works with objects of different classes through a common interface. For example:
Shape[] shapes = new Shape[3];
shapes[0] = new Circle();
shapes[1] = new Square();
shapes[2] = new Circle();
for (Shape shape : shapes) {
shape.draw();
}
In this code, an array of ‘Shape’ objects is populated with instances of ‘Circle’ and ‘Square.’ When we iterate through the array and call the ‘draw’ method, the appropriate implementation is invoked based on the actual object’s type. This is an example of polymorphism in action.
Interfaces and Polymorphism
In addition to method overriding, Java supports polymorphism through interfaces. An interface defines a contract that multiple classes can implement. It allows objects of different classes to be treated as instances of the interface.
interface Printable {
void print();
}
class Document implements Printable {
@Override
public void print() {
System.out.println("Printing a document");
}
}
class Image implements Printable {
@Override
public void print() {
System.out.println("Printing an image");
}
}
In this example, ‘Document’ and ‘Image’ both implement the ‘Printable’ interface by providing their own ‘print’ methods. As a result, you can use polymorphism to work with objects of these classes through the ‘Printable’ interface.
Benefits of Polymorphism
Polymorphism offers several advantages in Java and OOP, including:
- Flexibility: Polymorphism allows you to write more flexible and generic code that can work with different object types.
- Modularity: It promotes modularity and code reusability by defining a common interface for related classes.
- Extensibility: You can add new classes that implement the same interface without affecting existing code, making it easy to extend your applications.
Conclusion
Polymorphism is a fundamental concept in Java and object-oriented programming that enhances the flexibility and modularity of your code. It allows objects of different classes to be treated as instances of a common superclass or interface, simplifying code design and promoting reusability.