Por exemplo:
Imaginem 3 classes tais como: Pessoa, Carro e Arvore. Será que
poderíamos ter alguma relação entre elas? De cara pensamos que não.
Mas temos sim! Todos os três objetos poderiam ter um método
chamado getIdade() e cada um poderia implementar este método à sua
maneira, porém o retorno seria o mesmo: um inteiro que representa
a idade do objeto em questão.
- A classe Pessoa teria a idade de acordo com a diferença da data
atual com a data de nascimento;
- A classe Carro poderia considerar
além da data de compra a quilometragem corrente e fazer um cálculo
pra definir a idade;
- A classe Arvore consideraria a altura e o tipo de clima para definir a idade.
Mas todos os métodos retornariam apenas uma informação: UM INTEIRO
QUE REPRESENTA A IDADE. A idéia então seria fazer uma Interface que
definiria as propriedades e/ou comportamentos em comum a esse trio
de objetos.
Evidentemente o exemplo acima não é tão claro, pois é tanto quanto
estranho esse três objetos da vida real ser um exemplo de implementação
aplicado em sistemas pelo mundo. Então darei outro exemplo bem
simples e mais objetivo e de facílimo entendimento: os objetos
"Circulo" e "Quadrado".
O que eles tem em comum?
Os dois são "Figuras" não são? Sim!!
O que um quadrado e um círculo tem mais em comum?
Se podemos desenhá-los em um plano então podemos obter a
"Area" que ele ocupa nesse plano.
Finalmente temos:
- Nome de nossa Interface: IFigura
- Comportamento que ela define: getArea()
OBS: O "I" antes do nome "Figura" é um padrão utilizado que diz que se refere a uma (I) "Interface".
Como o próprio site
PHP.NET diz:
"Interfaces de Objetos permite a criação de código que especifica quais métodos e variáveis uma classe deve implementar, sem ter que definir como esses métodos serão tratados."(2)
Nossa interface especifica apenas o método: getArea()
Nossas Classes: Circulo e Quadrado
Nossas classes implementam a interface "IFigura" e assim como a definição devem também implementar obrigatoriamente as propriedades e comportamentos da interface herdada.
Assim, teremos o Polimorfismo, ou seja, "o programador pode tratar de generalidades e deixar o próprio ambiente de tempo de execução se preocupar com os detalhes específicos. O programador pode comandar uma ampla variedade de objetos, para se comportarem de maneira apropriada a esses objetos, mesmo que não conheça o tipos. (1) página 335"
Aonde o Polimorfismo entra?!!
Agora paremos e pensemos como seria o exemplo acima se por acaso tivéssemos não apenas 2 tipos de objetos e sim 10?
E se desejássemos obter, por algum motivo, a área de todos num conjunto de 100 objetos sortidos em qualquer proporção desses 10 tipos. Como faríamos?
Primeiro todos os 10 tipos (10 classes de tipos de figuras) implementariam nossa interface. Pois todos os objetos dessa classe são uma figura!
Já que todos são figuras, os colocaríamos num ARRAY de objetos ( array de IFigura ). A cada iteração teríamos acesso a um item do ARRAY aonde acessaríamos:
$arrObjsIFigura[ index ]->getArea();
Nesse momento NÃO saberíamos qual tipo de fato que contém aquele índice. Mas como TODOS os índices do array estão preenchidos com objetos do tipo "IFigura" ele teria a implementação do "getArea()". A cada iteração o ARRAY poderia ter um tipo diferente e ele teria uma maneira POLIMORFICA de calcular a área do objeto corrente, pois sabemos que cada objeto implementa o comportamento de maneira diferente.
Mas um problema surge! A tipagem da linguagem. Como sabemos uma das características de "linguagens de script" é que as variáveis são do tipo "variant", ou seja, seu tipo é definido em tempo de atribuição e muitas vezes são convertidas em tempo de execução. Essa característica impede que o conceito de Polimorfismo seja aplicado de maneira perfeita pois não teríamos garantia de ter um array de objetos de um único tipo já que, como sabemos, o array de PHP aceita qualquer que seja os atributos.
Definições como a da listagem abaixo são inconcebíveis em linguagens como Java e C#, pois elas são fortemente tipadas.