Polymorphism and Interfaces
An interface defines a set of methods a class must implement, declared with implements. Unlike extends, a class can implement multiple interfaces at once, and completely unrelated classes — Circle and Square share nothing but Shape here — can all satisfy the same interface.
public class Main {
interface Shape {
double area();
}
static class Circle implements Shape {
double radius;
Circle(double radius) {
this.radius = radius;
}
public double area() {
return 3.14159 * radius * radius;
}
}
static class Square implements Shape {
double side;
Square(double side) {
this.side = side;
}
public double area() {
return side * side;
}
}
public static void main(String[] args) {
Shape[] shapes = { new Circle(2), new Square(3) };
for (Shape s : shapes) {
System.out.println(s.area());
}
}
}12.56636 9.0
shapes is an array of Shape — the interface type — but each element still calls the correct class's own area() implementation. This is dynamic dispatch: which actual method runs is decided at runtime based on the object's real class, not the variable's declared type.
Next: abstract classes — a hybrid between a regular class and an interface, for sharing both a contract and real implementation code.
Practice exercise
Define an interface Named with a method name(). Define a class Dog that implements Named, with a field dogName and a name() method returning dogName. Write a method greet(Named n) that prints "Hello, " + n.name(). Call greet with a new Dog whose dogName is "Rex".