AnyCompiler

Polymorphism e Interfaces

Una interface define un conjunto de methods que una class debe implementar, declarado con implements. A diferencia de extends, una class puede implementar múltiples interfaces a la vez, y classes completamente no relacionadas — Circle y Square no comparten nada más que Shape aquí — pueden satisfacer todas la misma 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 es un array de Shape — el tipo interface — pero cada elemento igual llama a la implementación propia de area() de su class correcta. Esto es dynamic dispatch: qué method real se ejecuta se decide en tiempo de ejecución según la class real del object, no el tipo declarado de la variable.

Siguiente: abstract classes — un híbrido entre una class regular y una interface, para compartir tanto un contrato como código de implementación real.

Practice exercise

Define una interface Named con un method name(). Define una class Dog que implemente Named, con un field dogName y un method name() que devuelva dogName. Escribe un method greet(Named n) que imprima "Hello, " + n.name(). Llama a greet con un nuevo Dog cuyo dogName sea "Rex".