Médio Java
Template Method para preparo de bebidas
Enunciado
Implemente uma classe abstrata BebidaQuente com o template method preparar() que executa na ordem: ferverAgua(), preparar() e servir(). Os métodos ferverAgua() e servir() são concretos e imprimem mensagens genéricas. O método preparar() é abstrato. Crie as subclasses Cha e Cafe que implementam preparar() com mensagens específicas. No main, prepare um chá e um café.
Requisitos
- A classe
BebidaQuentedeve ser abstrata e conter o métodopreparar()comofinal. ferverAgua()eservir()devem ser concretos e reutilizados.ChaeCafedevem implementarpreparar()com mensagens distintas.- A saída deve mostrar a sequência correta para cada bebida.
Código inicial
abstract class BebidaQuente {
public final void preparar() {
// chame os métodos na ordem correta
}
protected void ferverAgua() {
System.out.println("Fervendo água...");
}
protected abstract void prepararBebida();
protected void servir() {
System.out.println("Servindo na xícara.");
}
}
class Cha extends BebidaQuente {
@Override
protected void prepararBebida() {
// implemente
}
}
class Cafe extends BebidaQuente {
@Override
protected void prepararBebida() {
// implemente
}
}
public class Main {
public static void main(String[] args) {
BebidaQuente cha = new Cha();
cha.preparar();
System.out.println("---");
BebidaQuente cafe = new Cafe();
cafe.preparar();
}
}
Saída esperada
Fervendo água...
Preparando o chá...
Servindo na xícara.
---
Fervendo água...
Preparando o café...
Servindo na xícara.
Ver dica
No método preparar(), chame ferverAgua(), depois prepararBebida() e por fim servir(). Nas subclasses, implemente prepararBebida() com a mensagem específica.
Mostrar solução
abstract class BebidaQuente {
// Template method: define a ordem dos passos
public final void preparar() {
ferverAgua();
prepararBebida();
servir();
}
protected void ferverAgua() {
System.out.println("Fervendo água...");
}
protected abstract void prepararBebida();
protected void servir() {
System.out.println("Servindo na xícara.");
}
}
class Cha extends BebidaQuente {
@Override
protected void prepararBebida() {
System.out.println("Preparando o chá...");
}
}
class Cafe extends BebidaQuente {
@Override
protected void prepararBebida() {
System.out.println("Preparando o café...");
}
}
public class Main {
public static void main(String[] args) {
BebidaQuente cha = new Cha();
cha.preparar();
System.out.println("---");
BebidaQuente cafe = new Cafe();
cafe.preparar();
}
}
Passo a passo
BebidaQuenteé abstrata e contém o métodopreparar()marcado comofinal, impedindo que subclasses alterem a ordem.ferverAgua()eservir()são concretos e fornecem passos comuns.prepararBebida()é abstrato e será implementado por cada subclasse.ChaeCafesobrescrevemprepararBebida()com suas mensagens específicas.- No
main, criamos instâncias e chamamospreparar(), que executa a sequência definida. - A saída mostra a ordem correta: ferver, preparar e servir.
Por que funciona
O Template Method define o esqueleto do algoritmo na superclasse, mas delega partes variáveis para as subclasses. O uso de final garante que a estrutura não seja modificada. Isso é um exemplo clássico de inversão de controle e reuso.
Erros comuns
- Não marcar
preparar()comofinal: subclasses poderiam sobrescrever e quebrar a sequência. - Esquecer de implementar
prepararBebida(): erro de compilação. - Colocar a lógica específica na classe base: perderia a generalização.
Outra forma de resolver
Poderia usar uma interface com métodos default para os passos comuns, mas classes abstratas permitem estado compartilhado e métodos protegidos.
Saída esperada
Fervendo água...
Preparando o chá...
Servindo na xícara.
---
Fervendo água...
Preparando o café...
Servindo na xícara.