Zumbie Health

Conversa entre Zumbis

Considere que zumbis podem conversar entre si através de um método especial pergunta, este método recebe uma pergunta (String) e retorna uma resposta (String). Podem ser feitas perguntas como a idade, nome e estado. Por exemplo, o método pode receber a pergunta:

"Qual a sua idade?"

e então retorna a idade.

Implemente este método nas três classes (GarotoZumbi, Monstro e Perfeito).

Resolução - Parte 1

Inicialmente vamos considerar o GarotoZumbi sem a parte de desenho porque simplifica a visualização da solução. O método pergunta seria implementado da maneira a seguir.

Duas observações:

  • Há críticas feitas ao uso do protected, mas eventualmente o usaremos para tornar as resoluções mais fáceis de ler.
  • O método estático integer.toString foi usado para a conversão de inteiro para String.

In [1]:
public class GarotoZumbiSoConversa
{
    protected int idade;
    protected String estado;
    protected String nome;
    
    public GarotoZumbiSoConversa(int idade, String estado, String nome) {
        this.idade = idade;
        this.estado = estado;
        this.nome = nome;
    }
    
    public String pergunta(String questao) {
        String resposta = "Não entendi a pergunta";
        if (questao.equalsIgnoreCase("Qual o seu nome?"))
            resposta = nome;
        else if (questao.equalsIgnoreCase("Qual a sua idade?"))
            resposta = Integer.toString(idade);
        else if (questao.equalsIgnoreCase("Qual o seu estado?"))
            resposta = estado;
        return resposta;
    }
}

GarotoZumbiSoConversa garoto = new GarotoZumbiSoConversa(2, "acordado", "Doriana");
System.out.println("Qual o seu nome?");
System.out.println(garoto.pergunta("Qual o seu nome?"));
System.out.println("Qual a sua idade?");
System.out.println(garoto.pergunta("Qual a sua idade?"));
System.out.println("Qual o seu estado?");
System.out.println(garoto.pergunta("Qual o seu estado?"));


Qual o seu nome?
Doriana
Qual a sua idade?
2
Qual o seu estado?
acordado

Resposta - Parte 2 - acrescentando herdeiros

As classes herdeiras dispõem do método automaticamente. Como a classe Perfeito tem um atributo a mais, ela estendeu o método acrescentando mais uma resposta. Essa forma de extensão é muito comum, você chama o método da superclasse e acrescenta o que desejar.


In [2]:
public class MonstroSoConversa extends GarotoZumbiSoConversa
{
    public MonstroSoConversa(int idade, String estado, String nome) {
        super(idade, estado, nome);
    }

}

public class PerfeitoSoConversa extends GarotoZumbiSoConversa
{
    protected String situacao = "normal";
    
    public PerfeitoSoConversa(int idade, String estado, String nome) {
        super(idade, estado, nome);
    }
    
    public String pergunta(String questao) {
        String resposta = super.pergunta(questao);
        if (questao.equalsIgnoreCase("Qual a sua situação?"))
            resposta = situacao;
        return resposta;
    }
}

MonstroSoConversa monst = new MonstroSoConversa(4, "dormindo", "Bonerges");
System.out.println("Qual o seu nome?");
System.out.println(monst.pergunta("Qual o seu nome?"));
System.out.println("Qual a sua idade?");
System.out.println(monst.pergunta("Qual a sua idade?"));
System.out.println("Qual o seu estado?");
System.out.println(monst.pergunta("Qual o seu estado?"));

System.out.println();

PerfeitoSoConversa perf = new PerfeitoSoConversa(3, "acordado", "Zandor");
System.out.println("Qual o seu nome?");
System.out.println(perf.pergunta("Qual o seu nome?"));
System.out.println("Qual a sua idade?");
System.out.println(perf.pergunta("Qual a sua idade?"));
System.out.println("Qual o seu estado?");
System.out.println(perf.pergunta("Qual o seu estado?"));
System.out.println("Qual a sua situação?");
System.out.println(perf.pergunta("Qual a sua situação?"));


Qual o seu nome?
Bonerges
Qual a sua idade?
4
Qual o seu estado?
dormindo

Qual o seu nome?
Zandor
Qual a sua idade?
3
Qual o seu estado?
acordado
Qual a sua situação?
normal

Resolução - Parte 3 - Combinando com as classes originais

Quando se trata de combinar os métodos nas classes originais temos uma questão em aberto:

  • Acrescentamos os métodos diretamente nas classes originais ou criamos heranças?

Parte 3 - Abordagem A - Alteração das classes originais

Veja a seguir a abordagem incluindo diretamente na classe original.


In [3]:
public class GarotoZumbi
{
    protected int idade;
    protected String estado;
    protected String nome;
    
    public GarotoZumbi(int idade, String estado, String nome) {
        this.idade = idade;
        this.estado = estado;
        this.nome = nome;
    }
    
    public void mostra(boolean imprimeNome) {
        // cabeleira
        if (idade >= 2)
            System.out.println("  *");
        
        // corpo com olhos
        if (estado.equalsIgnoreCase("acordado"))
            System.out.println(" o*o");
        else
            System.out.println(" -*-");
        
        // barba
        if (idade >= 3)
            System.out.println("*****");
        
        if (imprimeNome)
            System.out.println(nome);
        
        System.out.println();
    }
    
    public void mostra() {
        mostra(true);
    }
    
    public void cresce() {
        if (idade < 3)
            idade++;
        mostra();
    }
    
    public void acorda() {
        estado = "acordado";
        mostra();
    }
    
    public void dorme() {
        estado = "dormindo";
        mostra();
    }
    
    public String pergunta(String questao) {
        String resposta = "Não entendi a pergunta";
        if (questao.equalsIgnoreCase("Qual o seu nome?"))
            resposta = nome;
        else if (questao.equalsIgnoreCase("Qual a sua idade?"))
            resposta = Integer.toString(idade);
        else if (questao.equalsIgnoreCase("Qual o seu estado?"))
            resposta = estado;
        return resposta;
    }
}

public class Monstro extends GarotoZumbi
{
    public Monstro(int idade, String estado, String nome) {
        super(idade, estado, nome);
    }

    public void toString(boolean imprimeNome) {
        super.mostra(false);

        if (idade >= 4)
            System.out.println("#####");
        if (idade >= 5)
            System.out.println("/   \\");

        if (imprimeNome)
            System.out.println(nome);
    }

    public void cresce() {
        if (idade < 5)
            idade++;
        mostra();
    }
}

public class Perfeito extends GarotoZumbi
{
    protected String situacao = "normal";
    
    public Perfeito(int idade, String estado, String nome) {
        super(idade, estado, nome);
    }

    public Perfeito(int idade, String estado, String nome, String situacao) {
        super(idade, estado, nome);
        this.situacao = situacao;
    }

    public void mostra() {
        System.out.println("+-----+");

        if (idade >= 2)
            System.out.println("|     |");

        if (estado.equals("dormindo")) {
            System.out.println(" - -");
            System.out.println("|  _  |"); }
        else if (situacao.equals("normal")) {
            System.out.println("| o-o |");
            System.out.println("| ___ |"); }
        else if (situacao.equals("milionario")) {
            System.out.println("| $-$ |");
            System.out.println("| ___ |"); }
        else if (situacao.equals("doido")) {
            System.out.println("| @-@ |");
            System.out.println("|  ~  |");
        }

        if (idade < 3)
            System.out.println(" \\___/");
        else {
            System.out.println("|     |");
            System.out.println("\\_____/");
        }

            System.out.println(nome);
    }

    public void mudaSituacao() {
        String s[] = {"normal",
                      "milionario",
                      "doido" };

        int p;
        for (p = 0; p < s.length && !situacao.equals(s[p]); p++)
            /* nada */ ;

        p = (p + 1) % 3;
        situacao = s[p];

        mostra();
    }
    
    public String pergunta(String questao) {
        String resposta = super.pergunta(questao);
        if (questao.equalsIgnoreCase("Qual a sua situação?"))
            resposta = situacao;
        return resposta;
    }
}

GarotoZumbi garoto = new GarotoZumbi(2, "acordado", "Doriana");
garoto.mostra();
System.out.println("Qual o seu nome?");
System.out.println(garoto.pergunta("Qual o seu nome?"));
System.out.println("Qual a sua idade?");
System.out.println(garoto.pergunta("Qual a sua idade?"));
System.out.println("Qual o seu estado?");
System.out.println(garoto.pergunta("Qual o seu estado?"));

System.out.println();

Monstro monst = new Monstro(4, "dormindo", "Bonerges");
monst.mostra();
System.out.println("Qual o seu nome?");
System.out.println(monst.pergunta("Qual o seu nome?"));
System.out.println("Qual a sua idade?");
System.out.println(monst.pergunta("Qual a sua idade?"));
System.out.println("Qual o seu estado?");
System.out.println(monst.pergunta("Qual o seu estado?"));

System.out.println();

Perfeito perf = new Perfeito(3, "acordado", "Zandor");
perf.mostra();
System.out.println("Qual o seu nome?");
System.out.println(perf.pergunta("Qual o seu nome?"));
System.out.println("Qual a sua idade?");
System.out.println(perf.pergunta("Qual a sua idade?"));
System.out.println("Qual o seu estado?");
System.out.println(perf.pergunta("Qual o seu estado?"));
System.out.println("Qual a sua situação?");
System.out.println(perf.pergunta("Qual a sua situação?"));


  *
 o*o
Doriana

Qual o seu nome?
Doriana
Qual a sua idade?
2
Qual o seu estado?
acordado

  *
 -*-
*****
Bonerges

Qual o seu nome?
Bonerges
Qual a sua idade?
4
Qual o seu estado?
dormindo

+-----+
|     |
| o-o |
| ___ |
|     |
\_____/
Zandor
Qual o seu nome?
Zandor
Qual a sua idade?
3
Qual o seu estado?
acordado
Qual a sua situação?
normal

Resolução - Parte 3 - Abordagem B - Herança

O problema da herança é que criamos um novo ramo para o GarotoZumbi.

Desafio: o que acontece com as classes herdeiras do ramo original?


In [4]:
public class GarotoZumbiConversa extends GarotoZumbi
{
    public GarotoZumbiConversa(int idade, String estado, String nome) {
        super(idade, estado, nome);
    }
    
    public String pergunta(String questao) {
        String resposta = "Não entendi a pergunta";
        if (questao.equalsIgnoreCase("Qual o seu nome?"))
            resposta = nome;
        else if (questao.equalsIgnoreCase("Qual a sua idade?"))
            resposta = Integer.toString(idade);
        else if (questao.equalsIgnoreCase("Qual o seu estado?"))
            resposta = estado;
        return resposta;
    }
}

public class MonstroConversa extends Monstro
{
    public MonstroConversa(int idade, String estado, String nome) {
        super(idade, estado, nome);
    }

    public String pergunta(String questao) {
        String resposta = "Não entendi a pergunta";
        if (questao.equalsIgnoreCase("Qual o seu nome?"))
            resposta = nome;
        else if (questao.equalsIgnoreCase("Qual a sua idade?"))
            resposta = Integer.toString(idade);
        else if (questao.equalsIgnoreCase("Qual o seu estado?"))
            resposta = estado;
        return resposta;
    }
}

public class PerfeitoConversa extends Perfeito
{
    public PerfeitoConversa(int idade, String estado, String nome) {
        super(idade, estado, nome);
    }
    
    public String pergunta(String questao) {
        String resposta = "Não entendi a pergunta";
        if (questao.equalsIgnoreCase("Qual o seu nome?"))
            resposta = nome;
        else if (questao.equalsIgnoreCase("Qual a sua idade?"))
            resposta = Integer.toString(idade);
        else if (questao.equalsIgnoreCase("Qual o seu estado?"))
            resposta = estado;
        else if (questao.equalsIgnoreCase("Qual a sua situação?"))
            resposta = situacao;
        return resposta;
    }
}

GarotoZumbiConversa garoto = new GarotoZumbiConversa(2, "acordado", "Doriana");
garoto.mostra();
System.out.println("Qual o seu nome?");
System.out.println(garoto.pergunta("Qual o seu nome?"));
System.out.println("Qual a sua idade?");
System.out.println(garoto.pergunta("Qual a sua idade?"));
System.out.println("Qual o seu estado?");
System.out.println(garoto.pergunta("Qual o seu estado?"));

System.out.println();

MonstroConversa monst = new MonstroConversa(4, "dormindo", "Bonerges");
monst.mostra();
System.out.println("Qual o seu nome?");
System.out.println(monst.pergunta("Qual o seu nome?"));
System.out.println("Qual a sua idade?");
System.out.println(monst.pergunta("Qual a sua idade?"));
System.out.println("Qual o seu estado?");
System.out.println(monst.pergunta("Qual o seu estado?"));

System.out.println();

PerfeitoConversa perf = new PerfeitoConversa(3, "acordado", "Zandor");
perf.mostra();
System.out.println("Qual o seu nome?");
System.out.println(perf.pergunta("Qual o seu nome?"));
System.out.println("Qual a sua idade?");
System.out.println(perf.pergunta("Qual a sua idade?"));
System.out.println("Qual o seu estado?");
System.out.println(perf.pergunta("Qual o seu estado?"));
System.out.println("Qual a sua situação?");
System.out.println(perf.pergunta("Qual a sua situação?"));


  *
 o*o
Doriana

Qual o seu nome?
Doriana
Qual a sua idade?
2
Qual o seu estado?
acordado

  *
 -*-
*****
Bonerges

Qual o seu nome?
Bonerges
Qual a sua idade?
4
Qual o seu estado?
dormindo

+-----+
|     |
| o-o |
| ___ |
|     |
\_____/
Zandor
Qual o seu nome?
Zandor
Qual a sua idade?
3
Qual o seu estado?
acordado
Qual a sua situação?
normal

Comentário - Problema da Herança Múltipla

Teoricamente as classes MonstroConversa e PerfeitoConversa precisariam realizar uma Herança Múltipla para aproveitar as heranças de GarotoZumbiConversa mais Monstro ou Perfeito respectivamente.

O Java e a maioria das linguagens de programação modernas não suportam herança múltipla, pois ela torna a resolução de problemas intrincada.

O problema é que foi necessário se reimplementar o método pergunta nas subclasses.

Desafio: Como você resolveria esse problema sem reimplementar métodos?

Engajando zumbis na conversa

Escreva um método que permita engajar dois objetos zumbi em uma conversa. Após engajar dois zumbis, um deles deve ser capaz de contactar o outro para fazer perguntas.

Construa uma classe zumbi entrevistador que faça perguntas a outros zumbis para selecionar o mais velho entre eles. Se dois ou mais zumbis têm a mesma idade é dado preferência ao primeiro.

Escreva um programa em que um zumbi entrevistador entreviste três zumbis candidatos. Ele deve imprimir uma mensagem indicando o nome do mais velho entre os zumbis. Você deve engajar cada um dos candidatos com o entrevistador, que informará o resultado quando o método resultado for acionado.

Resolução - Parte 1

Voltamos ao exemplo do GarotoZumbiSoConversa para simplificar a solução.

Para conectar dois Zumbis acrescentamos o método conectar que recebe como parâmetro a referência a outro Zumbi e a guarda para usá-la quando necessário:

GarotoZumbiConectado outroGaroto;

public void conecta(GarotoZumbiConectado outroGaroto) {
    this.outroGaroto = outroGaroto;
}

Desafio: Eu poderia usar GarotoZumbiConversa na referência? Qual o impacto?


In [5]:
public class GarotoZumbiConectado extends GarotoZumbiConversa
{
    GarotoZumbiConectado outroGaroto;
    
    public GarotoZumbiConectado(int idade, String estado, String nome) {
        super(idade, estado, nome);
    }
    
    public void conecta(GarotoZumbiConectado outroGaroto) {
        this.outroGaroto = outroGaroto;
    }
}

Resolução - Parte 2


In [6]:
public class Entrevistador extends GarotoZumbiConectado {
    private GarotoZumbiConectado maisVelho = null;
    private int maisVelhoIdade = 0;
    
    public Entrevistador(int idade, String estado, String nome) {
        super(idade, estado, nome);
    }

    public void entrevista() {
        if (outroGaroto != null) {
            System.out.println("Qual a sua idade?");
            int outraIdade = Integer.parseInt(outroGaroto.pergunta("Qual a sua idade?"));
            System.out.println(outraIdade);
            if (outraIdade > maisVelhoIdade) {
                maisVelhoIdade = outraIdade;
                maisVelho = outroGaroto;
            }
        }
    }
    
    public GarotoZumbiConectado resultado() {
        return maisVelho;
    }
}

Entrevistador ent = new Entrevistador(57, "acordado", "Alcebíades");
ent.mostra();

System.out.println("\n=== Candidatos ===");
GarotoZumbiConectado doriana = new GarotoZumbiConectado(40, "acordado", "Doriana");
doriana.mostra();
GarotoZumbiConectado bonerges = new GarotoZumbiConectado(38, "acordado", "Bonerges");
bonerges.mostra();
GarotoZumbiConectado zandor = new GarotoZumbiConectado(35, "acordado", "Zandor");
zandor.mostra();

System.out.println("\n=== Entrevista ===");

doriana.mostra();
ent.conecta(doriana);
ent.entrevista();

bonerges.mostra();
ent.conecta(bonerges);
ent.entrevista();

zandor.mostra();
ent.conecta(zandor);
ent.entrevista();

System.out.println("\n=== Selecioando ===");
ent.resultado().mostra();


  *
 o*o
*****
Alcebíades


=== Candidatos ===
  *
 o*o
*****
Doriana

  *
 o*o
*****
Bonerges

  *
 o*o
*****
Zandor


=== Entrevista ===
  *
 o*o
*****
Doriana

Qual a sua idade?
40
  *
 o*o
*****
Bonerges

Qual a sua idade?
38
  *
 o*o
*****
Zandor

Qual a sua idade?
35

=== Selecioando ===
  *
 o*o
*****
Doriana