15.1. Polimorfismo

Continuando com o exemplo da secção anterior, seria útil, por exemplo, construirmos métodos que imprimissem no standard output:

Por exemplo, algo como:

Na classe ExemploPolimorfismoParametros,

 

Pergunta:

Na definição de cada método, de que tipo deve ser o parâmetro que representa o jogo sobre o qual queremos atuar?

Resposta:

O tipo do parâmetro deve ser o tipo comum a qualquer jogo, ou seja, o tipo Jogo.

Porquê? Relembrando que:

Na análise estática de tipos, executada pelo compilador, as seguintes regras são aplicadas:

percebemos então que as instruções

estão corretas, pois tanto o tipo de jogo1JogoComObjetivo –, como o tipo de jogo2JogoNumeroExatoJogadas – são subtipos de Jogo.

 

Chama-se polimorfismo à capacidade de tomar várias formas.

Nas invocações

imprimeDetalhes(jogo1); imprimeDetalhes(jogo2); imprimeVencedores(jogo1); imprimeVencedores(jogo2);

dizemos que as instanciações de parâmetros são polimórficas pois o parâmetro dos métodos, que é do tipo Jogo, recebe valores de tipos que não são exatamente o tipo Jogo, embora sejam seus subtipos.

 

A razão por trás das regras aplicadas pelo compilador é intuitiva.

Suponha uma variável ou parâmetro x declarada com o tipo T:

 

No nosso exemplo, no corpo dos métodos imprimeDetalhes e imprimeVencedores os seguintes métodos são invocados sobre o parâmetro j:

Ao parâmetro j, declarado como sendo do tipo Jogo, poderão ser atribuídas referências a objetos do tipo Jogo ou de qualquer dos seus subtipos (para já temos dois, mas no futuro poderão ser mais). Qualquer que seja esse subtipo, sabemos que implementará todos os métodos invocados sobre j, pois terão sido herdados (e possivelmente, até, redefinidos como, por exemplo, o método vencedores, que vamos examinar a seguir com mais pormenor).

Então, a classe ExemploPolimorfismoParametros ficaria assim:

 

 

 


 

Anterior: 15. Polimorfismo e ligação dinâmica

Seguinte: 15.2. Verificação estática de tipos