Uma lanchonete deseja um sistema de informação para gerenciar suas atividades. A lanchonete possui o gerente, cozinheiros e aténdentes. Eles possuem nome, cpf, salario. A lanchonete oferece os seguintes produtos: lanches, refrigerante e jantar por reserva.
Os seguintes tipos de lanches: pizza, sanduiche e cupcake. As pizzas podem ter borda ou não. Os lanches possuem id, preço, data de validade e peso. O sistema deverá criar um pedido que será composto pelo nome do cliente, nome do atendente, lanches comprados, valor total e data. O sistema deve gerar uma nota fiscal(print) para o cliente com os dados do pedido. A lanchonete também trabalha com encomendas. Cada encomenda tem o nome do cliente, os lanches, valor total e data de entrega.
Para o jantar o cliente entra em contato com a lanchonete e faz a reserva, com as informações data e quantidade de pessoas.
Crie uma classe para teste para testar o sistema lanchonete. Crie um pedido e faça uma reserva de jantar.
*Use herança e encapsulamento
*Defina as relações entre as classes.
*Extra: Use construtores sobrecarregados
*Extra: Sobrescreva métodos na subclasse da superclasse
Os seguintes tipos de lanches: pizza, sanduiche e cupcake. As pizzas podem ter borda ou não. Os lanches possuem id, preço, data de validade e peso. O sistema deverá criar um pedido que será composto pelo nome do cliente, nome do atendente, lanches comprados, valor total e data. O sistema deve gerar uma nota fiscal(print) para o cliente com os dados do pedido. A lanchonete também trabalha com encomendas. Cada encomenda tem o nome do cliente, os lanches, valor total e data de entrega.
Para o jantar o cliente entra em contato com a lanchonete e faz a reserva, com as informações data e quantidade de pessoas.
Crie uma classe para teste para testar o sistema lanchonete. Crie um pedido e faça uma reserva de jantar.
*Use herança e encapsulamento
*Defina as relações entre as classes.
*Extra: Use construtores sobrecarregados
*Extra: Sobrescreva métodos na subclasse da superclasse
Passo 1
O enunciado pede que a gente construa um pequeno sistema orientado a objeto (classes) para uma lanchonete. Pontos que o enunciado traz e que precisamos implementar:
- Pessoas da lanchonete: gerente, cozinheiros e atendentes. Cada um tem nome, CPF e salário.
- Produtos que a lanchonete oferece: lanches (tipos: pizza, sanduíche e cupcake), refrigerante e jantar por reserva.
- Requisitos dos lanches: têm id, preço, data de validade e peso. As pizzas ainda têm a característica “borda” (tem ou não).
- Deve existir a noção de pedido: composto por nome do cliente, nome do atendente, lista de lanches comprados, valor total e data. O sistema deve gerar uma nota fiscal (imprimir) do pedido.
- Encomendas: têm nome do cliente, lanches, valor total e data de entrega.
- Jantar por reserva: cliente informa data e quantidade de pessoas (reserva).
- Pedir para usar herança e encapsulamento.
- Extra: construtores sobrecarregados.
- Extra: sobrescrever métodos na subclasse (override).
Informações relevantes extraídas do enunciado:
- Precisamos modelar classes para funcionários (com herança), classes para lanches (com herança) e classes para Pedido, Encomenda e ReservaJantar.
- Pedidos trabalham com listas de lanches.
- Precisamos de métodos para calcular total e imprimir nota fiscal (print).
- Devemos aplicar encapsulamento: campos privados e acesso via getters/setters.
Passo 2
Decisão sobre o projeto (relação entre classes e por que):
- Vou criar uma superclasse abstrata Employee que tem os campos comuns (nome, cpf, salario). As subclasses serão Gerente, Cozinheiro e Atendente. Cada subclasse pode sobrescrever um método (por exemplo, getCargo ou toString) — isso mostra override.
- Para os produtos, vou criar uma classe abstrata Lanche com campos comuns (id, preco, validade, peso). Subclasses: Pizza, Sanduiche e Cupcake. A Pizza terá o campo adicional booleano borda. Vou mostrar construtores sobrecarregados em Lanche e em Pizza.
- Terei também uma classe Refrigerante (opcional) como outro tipo de produto (não-herdando de Lanche, porque refrigerante não tem peso e validade no mesmo sentido; mas poderia herdar se desejado).
- Pedido: classe com nomeCliente, nomeAtendente, lista de Lanche, data e método para calcular valor total e imprimir nota fiscal.
- Encomenda: similar ao Pedido, mas com dataEntrega.
- ReservaJantar: classe com nomeCliente, dataReserva e quantidadePessoas, com método para confirmar.
- Encapsulamento: todos os campos privados, acesso via getters/setters. Métodos públicos para operações (adicionar lanche, calcular total, imprimir nota).
- Sobrescritas (override): toString e um método getDescricao em cada subclasse de Lanche para mostrar detalhes específicos.
- Construtores sobrecarregados: vou fornecer pelo menos dois construtores em Lanche (um com validade, outro sem) e em Employee (um com salário, outro sem salário) e em Pizza (com e sem borda explicitada).
Agora vou mostrar as classes essenciais (código em Java), explicando o que cada parte faz.
Passo 3
Classe Employee e subclasses (herança e encapsulamento). Explicação: usamos uma superclasse abstrata para obrigar que todos os empregados tenham os campos comuns. Cada campo é privado (encapsulamento). Fornecemos getters/setters públicos. As subclasses sobrescrevem toString para mostrar o cargo.
Código (Employee.java, Gerente.java, Cozinheiro.java, Atendente.java):
import java.util.Objects;
public abstract class Employee {
private String nome;
private String cpf;
private double salario;
// Construtor padrão
public Employee(String nome, String cpf, double salario) {
this.nome = nome;
this.cpf = cpf;
this.salario = salario;
}
// Construtor sobrecarregado (salário opcional)
public Employee(String nome, String cpf) {
this(nome, cpf, 0.0);
}
// Getters e setters (encapsulamento)
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCpf() {
return cpf;
}
public void setCpf(String cpf) {
this.cpf = cpf;
}
public double getSalario() {
return salario;
}
public void setSalario(double salario) {
this.salario = salario;
}
// Método que pode ser sobrescrito pelas subclasses
public String getCargo() {
return "Funcionário";
}
@Override
public String toString() {
return getCargo() + ": " + nome + " (CPF: " + cpf + ", Salário: " + salario + ")";
}
}
public class Gerente extends Employee {
public Gerente(String nome, String cpf, double salario) {
super(nome, cpf, salario);
}
@Override
public String getCargo() {
return "Gerente";
}
}
public class Cozinheiro extends Employee {
public Cozinheiro(String nome, String cpf, double salario) {
super(nome, cpf, salario);
}
@Override
public String getCargo() {
return "Cozinheiro";
}
}
public class Atendente extends Employee {
public Atendente(String nome, String cpf, double salario) {
super(nome, cpf, salario);
}
// Exemplo de construtor sobrecarregado
public Atendente(String nome, String cpf) {
super(nome, cpf);
}
@Override
public String getCargo() {
return "Atendente";
}
}
Explicação didática curta:
- Por que abstrata? Para que não se crie um Employee genérico — queremos sempre um tipo específico (Gerente, Cozinheiro, Atendente).
- Encapsulamento: campos privados e métodos públicos controlam acesso e evitam manipulação direta.
Passo 4
Classe Lanche e subclasses (Pizza, Sanduiche, Cupcake). Explicação: Lanche é abstrata porque não queremos instanciar um “Lanche” genérico sem tipo. Campos privados: id, preco, validade, peso. Métodos para obter preço e descrição. Sobrescrita (override) de getDescricao e toString nas subclasses para apresentar informações específicas.
Código (Lanche.java, Pizza.java, Sanduiche.java, Cupcake.java):
import java.time.LocalDate;
public abstract class Lanche {
private String id;
private double preco;
private LocalDate validade;
private double peso; // em gramas, por exemplo
// Construtor completo
public Lanche(String id, double preco, LocalDate validade, double peso) {
this.id = id;
this.preco = preco;
this.validade = validade;
this.peso = peso;
}
// Construtor sobrecarregado (sem validade informada)
public Lanche(String id, double preco, double peso) {
this(id, preco, null, peso);
}
// Getters e setters
public String getId() {
return id;
}
public double getPreco() {
return preco;
}
public void setPreco(double preco) {
this.preco = preco;
}
public LocalDate getValidade() {
return validade;
}
public void setValidade(LocalDate validade) {
this.validade = validade;
}
public double getPeso() {
return peso;
}
public void setPeso(double peso) {
this.peso = peso;
}
// Método que será sobrescrito para dar descrição específica
public String getDescricao() {
return "Lanche genérico (id=" + id + ")";
}
@Override
public String toString() {
String v = (validade == null) ? "indefinida" : validade.toString();
return getDescricao() + " | Preço: " + String.format("%.2f", preco) + " | Validade: " + v + " | Peso: " + peso + "g";
}
}
public class Pizza extends Lanche {
private boolean borda;
// Construtor com validade
public Pizza(String id, double preco, LocalDate validade, double peso, boolean borda) {
super(id, preco, validade, peso);
this.borda = borda;
}
// Construtor sobrecarregado (sem validade)
public Pizza(String id, double preco, double peso, boolean borda) {
super(id, preco, peso);
this.borda = borda;
}
public boolean hasBorda() {
return borda;
}
public void setBorda(boolean borda) {
this.borda = borda;
}
@Override
public String getDescricao() {
return "Pizza (id=" + getId() + ", borda=" + (borda ? "sim" : "não") + ")";
}
}
public class Sanduiche extends Lanche {
public Sanduiche(String id, double preco, LocalDate validade, double peso) {
super(id, preco, validade, peso);
}
public Sanduiche(String id, double preco, double peso) {
super(id, preco, peso);
}
@Override
public String getDescricao() {
return "Sanduíche (id=" + getId() + ")";
}
}
public class Cupcake extends Lanche {
public Cupcake(String id, double preco, LocalDate validade, double peso) {
super(id, preco, validade, peso);
}
public Cupcake(String id, double preco, double peso) {
super(id, preco, peso);
}
@Override
public String getDescricao() {
return "Cupcake (id=" + getId() + ")";
}
}
Explicação didática curta:
- Observe os dois construtores em Lanche: um com validade e outro sem — isso é sobrecarga de construtor.
- Em Pizza temos outro construtor sobrecarregado: com e sem validade (reaproveitamos o construtor da superclasse).
Passo 5
Pedido, Encomenda e ReservaJantar. Explicação: estas classes controlam operações típicas (calcular total, imprimir nota, confirmar reserva). Usaremos List<Lanche> para armazenar os lanches do pedido. O método calcularTotal soma os preços dos lanches — simples e direto.
Código (Pedido.java, Encomenda.java, ReservaJantar.java):
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
public class Pedido {
private String nomeCliente;
private String nomeAtendente;
private List<Lanche> lanches;
private double valorTotal;
private LocalDate data;
public Pedido(String nomeCliente, String nomeAtendente, List<Lanche> lanches, LocalDate data) {
this.nomeCliente = nomeCliente;
this.nomeAtendente = nomeAtendente;
// fazemos uma cópia defensiva da lista para não expor a lista interna
this.lanches = new ArrayList<>(lanches);
this.data = data;
this.valorTotal = calcularTotal();
}
// Método que soma os preços dos lanches
private double calcularTotal() {
double total = 0.0;
for (Lanche l : lanches) {
total += l.getPreco();
}
return total;
}
public void imprimirNotaFiscal() {
System.out.println("------ NOTA FISCAL ------");
System.out.println("Cliente: " + nomeCliente);
System.out.println("Atendente: " + nomeAtendente);
System.out.println("Data: " + data);
System.out.println("Itens:");
for (Lanche l : lanches) {
System.out.println(" - " + l.toString());
}
System.out.println("Valor total: R$ " + String.format("%.2f", valorTotal));
System.out.println("-------------------------");
}
// Getters (se quiser atualizar os lanches, podemos criar métodos específicos)
public double getValorTotal() {
return valorTotal;
}
public List<Lanche> getLanches() {
return new ArrayList<>(lanches);
}
}
public class Encomenda {
private String nomeCliente;
private List<Lanche> lanches;
private double valorTotal;
private LocalDate dataEntrega;
public Encomenda(String nomeCliente, List<Lanche> lanches, LocalDate dataEntrega) {
this.nomeCliente = nomeCliente;
this.lanches = new ArrayList<>(lanches);
this.dataEntrega = dataEntrega;
this.valorTotal = calcularTotal();
}
private double calcularTotal() {
double total = 0.0;
for (Lanche l : lanches) {
total += l.getPreco();
}
return total;
}
public void imprimirEncomenda() {
System.out.println("---- ENCOMENDA ----");
System.out.println("Cliente: " + nomeCliente);
System.out.println("Data de entrega: " + dataEntrega);
System.out.println("Itens:");
for (Lanche l : lanches) {
System.out.println(" - " + l.toString());
}
System.out.println("Valor total: R$ " + String.format("%.2f", valorTotal));
System.out.println("-------------------");
}
}
public class ReservaJantar {
private String nomeCliente;
private LocalDate dataReserva;
private int quantidadePessoas;
public ReservaJantar(String nomeCliente, LocalDate dataReserva, int quantidadePessoas) {
this.nomeCliente = nomeCliente;
this.dataReserva = dataReserva;
this.quantidadePessoas = quantidadePessoas;
}
public void confirmarReserva() {
System.out.println("=== RESERVA DE JANTAR ===");
System.out.println("Cliente: " + nomeCliente);
System.out.println("Data: " + dataReserva);
System.out.println("Número de pessoas: " + quantidadePessoas);
System.out.println("Reserva confirmada! Obrigado.");
System.out.println("=========================");
}
// Getters e setters
public LocalDate getDataReserva() {
return dataReserva;
}
public int getQuantidadePessoas() {
return quantidadePessoas;
}
}
Explicação didática curta:
- Ao construir o pedido, calculamos o total automaticamente e armazenamos em valorTotal.
- imprimirNotaFiscal mostra como gerar a “nota fiscal” (um simples print formatado).
- Encomenda é análoga ao Pedido, mas com dataEntrega.
- ReservaJantar tem método confirmarReserva para simular a confirmação.
Passo 6
Observações didáticas sobre encapsulamento, herança, sobrecarga e sobrescrita:
- Encapsulamento: todos os campos importantes foram declarados como private. Para acessar ou modificar, usamos getters/setters. Isso nos permite validar mudanças no futuro (ex.: impedir salário negativo).
- Herança: Employee é superclasse; Gerente, Cozinheiro e Atendente herdam campos e métodos. Lanche é superclasse abstrata; Pizza, Sanduiche, Cupcake herdam.
- Sobrescrita (override): sobrescrevemos getCargo()/toString() em Employee subclasses, e getDescricao() em cada Lanche. Isso permite comportamento específico por tipo.
- Sobrecarga de construtores: Lanche tem dois construtores; Pizza também; Atendente tem versão com e sem salário. A sobrecarga permite diferentes formas de criar objetos conforme a informação disponível.
- Boas práticas: usamos cópias defensivas de listas no construtor (new ArrayList<>(lanches)) para evitar que a lista interna seja alterada fora da classe.
Passo 7
Como testar: criar uma classe de teste (com main) que:
- cria um atendente (Atendente),
- cria alguns lanches (Pizza, Sanduiche, Cupcake),
- monta uma lista de lanches,
- cria um Pedido com esses lanches e chama imprimirNotaFiscal(),
- cria uma ReservaJantar e chama confirmarReserva().
Abaixo, na seção final (
Resposta
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
public class TestLanchonete {
public static void main(String[] args) {
// Criando um atendente (poderia ser criado também gerente e cozinheiro)
Atendente atendente = new Atendente("Maria Silva", "11122233344", 1800.0);
// Criando alguns lanches
Pizza pizza = new Pizza("P001", 29.90, LocalDate.of(2025, 12, 31), 800, true);
Sanduiche sanduiche = new Sanduiche("S001", 12.50, LocalDate.of(2025, 11, 30), 250);
Cupcake cupcake = new Cupcake("C001", 5.00, LocalDate.of(2025, 10, 15), 80);
// Montando a lista de lanches comprados
List<Lanche> lanches = new ArrayList<>();
lanches.add(pizza);
lanches.add(sanduiche);
lanches.add(cupcake);
// Criando um pedido
Pedido pedido = new Pedido("João Pereira", atendente.getNome(), lanches, LocalDate.now());
// Imprimindo a nota fiscal (print)
pedido.imprimirNotaFiscal();
// Criando uma reserva de jantar
ReservaJantar reserva = new ReservaJantar("Ana Costa", LocalDate.of(2025, 11, 20), 4);
reserva.confirmarReserva();
// Exemplo de encomenda (opcional)
Encomenda encomenda = new Encomenda("Carlos Souza", lanches, LocalDate.of(2025, 10, 5));
encomenda.imprimirEncomenda();
}
}