AnyCompiler

Polymorphism e Interfaces

Uma interface define um conjunto de methods que uma class deve implementar, declarado com implements. Diferente de extends, uma class pode implementar múltiplas interfaces ao mesmo tempo, e classes completamente não relacionadas — Circle e Square não compartilham nada além de Shape aqui — podem todas satisfazer a mesma 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 é um array de Shape — o tipo interface — mas cada elemento ainda chama a implementação própria de area() da sua class correta. Isso é dynamic dispatch: qual method real roda é decidido em tempo de execução com base na class real do object, não no tipo declarado da variável.

A seguir: abstract classes — um híbrido entre uma class comum e uma interface, para compartilhar tanto um contrato quanto código de implementação real.

Practice exercise

Defina uma interface Named com um method name(). Defina uma class Dog que implemente Named, com um field dogName e um method name() que retorne dogName. Escreva um method greet(Named n) que imprima "Hello, " + n.name(). Chame greet com um novo Dog cujo dogName seja "Rex".