Onde eu uso Interfaces?
Uma explicação simples sobre o uso de interfaces na linguagem de programação PHP.
As interfaces são utilizadas quando você precisa ter certeza de que um objeto responde a determinados métodos, independente de que tipo ele seja.
Elas funcionam como uma espécie de contrato: você cria uma interface com o esqueleto dos métodos que serão obrigatórios, então qualquer classe que implemente essa interface será obrigada a escrever esses métodos.
Neste exemplo, qualquer classe que implementa a interface Arrayable precisará implementar um método toArray():
Exemplo: garantindo que um objeto possa ser tributado
No artigo sobre o Princípio do Aberto/Fechado, vimos uma classe chamada de impostômetro, que é responsável por somar o valor dos impostos dos objetos que ela recebe (remédios, cosméticos, serviços diversos, etc.).
Ela é usada da seguinte forma:
Como o cálculo de impostos é diferente de acordo com o produto ou serviço, cada classe que representa algo “tributável” precisa calcular e retornar o valor de seus próprios impostos.
O programador definiu que as classes que representam itens tributáveis precisam implementar um método chamado getValorImpostos() que retorna esse valor:
Como o programador fez o próprio PHP avisar que qualquer objeto recebido precisa ter o método necessário?
- Criando uma interface chamada Tributavel;
- Definindo que quem implementa essa interface tem que escrever um método getValorImpostos();
- Obrigando o argumento $item do método somar() a ser um objeto do tipo Tributavel (indução de tipo).
Desta forma, sempre que alguém quiser incluir um novo item tributável, basta implementar a interface Tributavel que o impostômetro funcionará normalmente.
O que acontece quando violo a interface?
Se eu crio uma classe implementando a interface Tributavel e esqueço de implementar o método getValorImpostos(), o PHP cospe um erro fatal:
Class Zoeira contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Tributavel::getValorImpostos)
Se alguém por engano passar um objeto que não implementa a interface para o método Impostometro::somar(Tributavel $item), o PHP também cuspirá um erro:
Argument 1 passed to Impostometro::somar() must be an instance of Tributavel, instance of Zoeira given
Interfaces vs métodos abstratos
Interfaces funcionam de uma forma muito parecida com classes e métodos abstratos. A diferença é que uma classe pode implementar várias interfaces, mas só pode estender uma única classe-mãe.
Veja o exemplo acima reescrito com uma classe abstrata:
Quando devo usar interfaces ao invés de classes abstratas?
- Quando a hierarquia de classes não faz sentido ou não é possível;
- Quando preciso implantar mais de uma interface;
- Quando favoreço o uso de composição ao invés de herança.
Imagem da capa de Michael Bentley.