AnyCompiler

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());
        }
    }
}
Output
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".