What is polymorphism, and how do you write code that works with different implementations without knowing them in advance?
Polymorphism means many shapes behind one name. The loop above holds references of type Shape, and each one points at a different runtime object. When the loop calls area, the program does not ask what the reference's declared type is; it asks what the object actually is, and it dispatches to the Circle implementation or the Square implementation accordingly. The total area printed is 21.57.
public class Main {
public static void main(String[] args) {
java.util.List<Shape> shapes = new java.util.ArrayList<>();
shapes.add(new Circle(2.0));
shapes.add(new Square(3.0));
double total = 0;
for (Shape s : shapes) {
total += s.area();
}
System.out.println("total area = " + String.format("%.2f", total));
}
}
abstract class Shape {
abstract double area();
}
class Circle extends Shape {
private final double radius;
Circle(double radius) { this.radius = radius; }
double area() { return Math.PI * radius * radius; }
}
class Square extends Shape {
private final double side;
Square(double side) { this.side = side; }
double area() { return side * side; }
}The mechanism is dynamic method dispatch, and it is what makes the loop possible. The compiler checks that Shape has an area method and generates a call site that looks the method up in the object's actual class at run time. The same reference type can therefore point at any implementation of the contract, and the code that uses it never has to be edited when a new implementation appears.
Notice that the loop contains no if statements. That is the payoff. A version that branched on the runtime type would need editing every time a new shape was added, and the branch would spread to every place that handled shapes. Polymorphism moves that decision to the class that owns the behaviour.
The trade-off worth naming is that the reader has to open the implementation to know what will run. For a small program that indirection can cost more than it saves, so polymorphism earns its keep when there are several implementations, or when the count is expected to grow.