Ainda se lembra do método terminou
, na classe Jogo
? Não lhe demos a atenção devida pois considerámos que não há nenhuma maneira comum e geral de terminar um jogo, contrariamente ao cálculo do(s) vencedor(es), em que considerámos que o mais comum era que vencesse o jogador com o maior número de pontos.
Definimos uma implementação específica para o método terminou
em cada uma das subclasses de Jogo
e "esquecemos" esse método na classe Jogo
.
Implementámos assim na subclasse JogoComObjetivo
:
/**
* Este jogo jah terminou?
*/
public boolean terminou() {
return this.maiorPontuacao() >= objetivo;
}
E da seguinte forma na subclasse JogoNumeroExatoJogadas
:
xxxxxxxxxx
/**
* Este jogo jah terminou?
*/
public boolean terminou() {
return this.jahTerminou;
}
Se na classe Jogo
tivermos
xxxxxxxxxx
/**
* Este jogo jah terminou?
*/
public boolean terminou () {
??????
}
já sabemos que o compilador dá erro. Mas a verdade é que não sabemos como implementar este método na classe Jogo
pois ao nível desta classe não há informação suficiente para decidir quando é que um jogo termina.
Vamos agora examinar o que acontece se a classe Jogo
não declarar nenhum método terminou
.
No seguinte programa, o método terminou
é invocado sobre dois objetos cujo tipo declarado é Jogo
, mas cujos tipos concretos são JogoComObjetivo
e JogoNumeroExatoJogadas
:
xpublic class ExemploNaoExisteMetodo {
public static void main(String[] args) {
Jogo[] meusJogos = new Jogo[2];
meusJogos[0] = new JogoComObjetivo("Spiral", 25);;
meusJogos[1] = new JogoNumeroExatoJogadas("Harvest Kingdom",1);;
meusJogos[0].juntarJogador("Maria");
meusJogos[0].juntarJogador("Pedro");
meusJogos[1].juntarJogador("John Snow");
meusJogos[1].juntarJogador("Daenerys Targaryen");
meusJogos[0].registarPontosJogada("Maria", 11);
meusJogos[0].registarPontosJogada("Pedro", 26);
meusJogos[1].registarPontosJogada("John Snow", 10);
meusJogos[1].registarPontosJogada("Daenerys Targaryen", 10);
for(int i = 0 ; i < meusJogos.length ; i++) {
// metodo terminou eh invocado
if(meusJogos[i].terminou()){
System.out.println("Jogo " + meusJogos[i].designacao() +
" terminou");
}
}
}
Como o método terminou
não está definido na classe Jogo
, que é o tipo declarado da variável meusJogos
, a compilação produz o seguinte erro nesta classe: The method terminou() is undefined for the type Jogo.
Na verdade, este erro só aconteceria se a classe Jogo
não implementasse o interface Ganhavel
(ver secção 14). Como a classe Jogo
implementa o interface Ganhavel
, então o efeito de não implementar o método boolean terminou()
seria o erro de compilação: The type Jogo must implement the inherited abstract method Ganhavel.terminou().
Na próxima secção vamos ver como o conceito de classe abstrata nos permite resolver este problema.
Anterior: 15.7. Métodos genéricos
Seguinte: 16.1. A classe abstrata Jogo