Polymorphism

Polymorphism, a core concept in OOP, refers to the ability of different classes to be treated as instances of the same class through a common interface. This ability allows methods to use objects of different classes interchangeably, providing flexibility and scalability in code design.

Example of Polymorphism in Java

To illustrate polymorphism, consider a collection of geometric shapes. In Java, we can create a class MyShapeCollection that can store various shapes, like circles and rectangles, and compute their collective area. Here's how it's implemented:

public class MyShapeCollection {
  private List<Shape> shapes;

  public MyShapeCollection() {
    shapes = new ArrayList<>();
  }

  public void add(Shape shape) {
    shapes.add(shape);
  }

  public double getTotalArea() {
    double total = 0;
    for (Shape shape : shapes) {
      total += shape.area();
    }
    return total;
  }
}

This class can handle any object that is a subclass of Shape. For instance:

MyShapeCollection myShapes = new MyShapeCollection();
myShapes.add(new Circle(2.0));
myShapes.add(new Rectangle(1.0, 3.0));
myShapes.add(new Rectangle(4.0, 2.0));
System.out.println("Total Area: " + myShapes.getTotalArea());

How Polymorphism Works

In this example, the MyShapeCollection class uses a list of Shape objects. Despite Shape being an abstract class, its subclasses like Circle and Rectangle can be added to this list. When the area() method is called on these objects, the specific implementation of area() in each subclass is executed. This dynamic method dispatch—where the method that is executed depends on the object's actual type (determined at runtime)—is a fundamental aspect of polymorphism.

Benefits and Application

Polymorphism allows for writing generic and reusable code. The MyShapeCollection class can work with any new shape type that is a subclass of Shape, without requiring modification. This makes the code more maintainable and extensible, as new shapes can be easily integrated.

In summary, polymorphism in OOP enables objects of different classes to be treated as objects of a common super class, facilitating flexible and scalable software design. It's a powerful tool for writing concise, maintainable, and adaptable code.