4. Polimorfismo
- Crie uma classe CentralControle que possui uma lista de veículos autônomos.
- Implemente um método executarMissao() que percorre a lista e chama polimorficamente os métodos informacoes(), ativarSisțema(), mover() e navegar().
Além disso,
✓ Adicione um método calcularEficiência() em Veiculo como abstrato.
✓ Cada classe concreta deve implementar esse método com uma lógica diferente (ex.: carro retorna eficiência baseada em consumo de combustível, drone baseada em bateria, ônibus basȩada em número de passageiros).
✓ No exceutarMissão(), exiba também a eficiência calculada de cada veiculo
✓ Adicione um método calcularEficiência() em Veiculo como abstrato.
✓ Cada classe concreta deve implementar esse método com uma lógica diferente (ex.: carro retorna eficiência baseada em consumo de combustível, drone baseada em bateria, ônibus basȩada em número de passageiros).
✓ No exceutarMissão(), exiba também a eficiência calculada de cada veiculo
Passo 1
O enunciado pede que eu crie um sistema com polimorfismo que envolva:
- Uma classe chamada CentralControle que possui uma lista de veículos autônomos.
- Um método
executarMissao()emCentralControleque percorre essa lista e, para cada veículo, chama polimorficamente os métodosinformacoes(),ativarSistema(),mover()enavegar(). - Em
Veiculodeve ser adicionado o métodocalcularEficiência()como abstrato. - Cada classe concreta (por exemplo
Carro,Drone,Onibus) deve implementarcalcularEficiência()com lógica diferente (ex.: carro → eficiência baseada em consumo de combustível; drone → baseada em bateria; ônibus → baseada em número de passageiros). - No
executarMissao()também deve ser exibida a eficiência calculada de cada veículo.
Informações relevantes fornecidas:
- Métodos obrigatórios a serem chamados durante a missão:
informacoes(),ativarSistema(),mover(),navegar(). - Deve existir
calcularEficiência()emVeiculocomo método abstrato. - Cada subclasse deve implementar
calcularEficiência()com lógica distinta. executarMissao()deve percorrer a lista e exibir a eficiência de cada veículo.
Passo 2
Decisão sobre linguagem e abordagem (sem resolver ainda): vou usar Java para implementar esse exemplo porque Java é uma linguagem orientada a objetos bem clara para explicar classes abstratas, herança e polimorfismo — e é muito usada em exercícios acadêmicos de POO. A estrutura que vou criar é:
abstract class Veiculocom métodos abstratos (incluindocalcularEficiencia()).- Subclasses concretas:
Carro,Drone,Onibusque implementam os métodos abstratos e cada uma com sua lógica de eficiência. CentralControlecomList<Veiculo>e métodoexecutarMissao()que chama polimorficamente os métodos pedidos e imprime a eficiência.
Vou implementar também um
Main de exemplo que instancia alguns veículos, adiciona ao CentralControle e chama executarMissao() para mostrar o comportamento.Passo 3
Conceitos-chave que vou usar (explicação didática curta para a prova):
- Classe abstrata: uma classe que não pode ser instanciada e pode conter métodos abstratos (assinaturas sem implementação). Serve para definir uma interface comum e forçar subclasses a implementar detalhes.
- Método abstrato: declarado na classe abstrata; obriga as subclasses a fornecer a implementação.
- Polimorfismo dinâmico (dispatch dinâmico): quando se tem uma referência do tipo da superclasse (
Veiculo v = new Carro(...);) e se chamav.mover(), a implementação que será executada é a da classe concreta (Carro) em tempo de execução. Isso é essencial paraexecutarMissao()— ele só precisa conhecerVeiculo. - Upcasting: atribuir objeto concreto para uma referência do tipo abstrato/superclasse; isso permite colocar diferentes tipos na mesma lista.
- Boas práticas: cada subclasse implementa
informacoes()mostrando o que ela é e quais dados relevantes ela tem — isso ajuda a saber o que significa a eficiência que será exibida.
Passo 4
Projeto da classe base
Veiculo (o que ela deve conter e por quê):- Atributo comum:
id(identificador), pode ter outros campos dependendo do tipo. - Métodos (podem ser abstratos ou com comportamento padrão):
informacoes()— mostra dados do veículo (pode ser abstrato para forçar implementação específica).ativarSistema()— simula a ativação dos sistemas.mover()— ação de mover.navegar()— ação de navegação/autonomia.calcularEficiencia()— obrigatório e abstrato (retornadouble).
- Vou tornar os métodos citados abstratos (exceto o construtor), pois cada classe concreta pode querer um comportamento próprio de exibição/ativação/movimento/navegação.
Passo 5
Lógica de eficiência que vou usar (explicando como calcular — útil para a prova):
- Carro:
- Atributo:
consumoLitrosPor100km(quanto o carro consome em litros a cada 100 km). - Eficiência:
kmPorLitro = 100 / consumoLitrosPor100km. Esse número fica fácil de interpretar (quanta distância o carro percorre por litro).
- Atributo:
- Drone:
- Atributos:
autonomiaMinutosPorCarga(minutos de voo com bateria cheia) eporcentagemBateria(nível atual, 0 a 100). - Eficiência:
minutosRestantes = autonomiaMinutosPorCarga * (porcentagemBateria / 100). Interpretação: tempo de voo restante com a carga atual.
- Atributos:
- Ônibus:
- Atributos:
consumoLitrosPor100kmepassageiros. - Eficiência:
passengerKmPerLiter = passageiros * (100 / consumoLitrosPor100km). Interpretação: quantos “passageiro·quilômetros” o ônibus entrega por litro (é uma métrica comum para transporte coletivo: quantos passageiros transportados por distância por unidade de combustível).
- Atributos:
Observação importante (para a prova): cada classe pode escolher unidades diferentes para a “eficiência”, o que é aceitável — o que importa é que cada implementação faça sentido na métrica escolhida. Por isso, nas
informacoes() de cada classe vou explicar qual unidade aquela eficiência representa.Passo 6
Implementação (explicada passo a passo). Primeiro a estrutura da classe
Veiculo (em Java) e por que cada parte está ali:abstract class Veiculocomprotected String id;- Construtor que recebe
id. - Assinaturas abstratas:
public abstract void informacoes();public abstract void ativarSistema();public abstract void mover();public abstract void navegar();public abstract double calcularEficiencia();
Explicação didática de cada método:
informacoes(): cada veículo mostra seu tipo e atributos (ajuda a entender a eficiência).ativarSistema(): simula iniciar sensores, ligar motores, etc.mover()enavegar(): representam comportamentos distintos (mover: deslocamento; navegar: planejar/seguir rota).calcularEficiencia(): retorna número que traduz a eficiência segundo lógica específica da subclasse.
Passo 7
Implementações das subclasses com exemplos concretos:
Carro:- Campos:
consumoLitrosPor100km. - Implementa
informacoes()mostrandoide consumo. calcularEficiencia()retorna100.0 / consumoLitrosPor100km(km por litro).
- Campos:
Drone:- Campos:
autonomiaMinutosPorCarga,porcentagemBateria. calcularEficiencia()retornaautonomiaMinutosPorCarga * (porcentagemBateria / 100.0)(minutos restantes).
- Campos:
Onibus:- Campos:
consumoLitrosPor100km,passageiros. calcularEficiencia()retornapassageiros * (100.0 / consumoLitrosPor100km)(passenger-km por litro).
- Campos:
Em cada método
ativarSistema(), mover(), navegar() vou colocar mensagens simples para demonstrar comportamento (ex.: “Sensores do drone inicializados”, “Ônibus iniciando rota”).Passo 8
Classe
CentralControle e o método executarMissao() (explicação prática):CentralControletemprivate List<Veiculo> veiculos = new ArrayList<>();- Método
adicionarVeiculo(Veiculo v)para popular a lista. - Método
executarMissao():- Percorre
veiculos(for-each). - Para cada
Veiculo vchama, nesta ordem:v.informacoes();v.ativarSistema();v.mover();v.navegar();double eficiencia = v.calcularEficiencia();- Imprime a eficiência (formatada).
- Percorre
- Observação didática: o código em
executarMissao()conhece apenas o tipoVeiculo, não as classes concretas; ainda assim, em tempo de execução cada chamada é resolvida para a implementação correta — isso é polimorfismo.
Passo 9
Exemplo completo de uso (main) e saída esperada:
- No
main, instanciar:Carro c1 = new Carro("Carro-01", 8.5); // 8,5 L/100kmDrone d1 = new Drone("Drone-Alpha", 30.0, 75.0); // 30 min por carga, 75% bateriaOnibus o1 = new Onibus("Onibus-100", 40.0, 50); // 40 L/100km, 50 passageiros
- Adicionar ao
CentralControlee chamarexecutarMissao(). - Saída esperada (exemplo):
- Informações do veículo
- Mensagens de ativação, movimento, navegação
- “Eficiência calculada: 11,76” (por exemplo para carro; aqui 100/8.5 ≈ 11.76 km/L)
- Para drone: “Eficiência calculada: 22,50” (minutos restantes: 30 * 0,75 = 22.5)
- Para ônibus: “Eficiência calculada: 125,00” (passenger-km/L: 50 * (100/40) = 125)
Passo 10
Dicas rápidas para a prova (resumidas e úteis):
- Lembre-se: ao chamar métodos em uma referência do tipo da superclasse, a JVM (ou mecanismo da linguagem) escolhe a implementação da subclasse em tempo de execução.
- Método abstrato obriga implementação nas subclasses concretas — útil para garantir que
calcularEficiencia()exista para todo veículo. - Pense nas unidades de eficiência e informe-as em
informacoes()para evitar confusão. - Em provas, explique a métrica que você escolheu quando pedir para “calcular eficiência”; mostrar a fórmula ajuda a justificar a implementação.
Resposta
Abaixo está um exemplo completo em Java que implementa tudo o que foi pedido. Copie e cole num arquivo
Main.java (ou vários arquivos conforme preferir) e rode para ver o comportamento.import java.util.ArrayList;
import java.util.List;
// Classe abstrata Veiculo
abstract class Veiculo {
protected String id;
public Veiculo(String id) {
this.id = id;
}
public abstract void informacoes();
public abstract void ativarSistema();
public abstract void mover();
public abstract void navegar();
public abstract double calcularEficiencia();
}
// Carro: eficiência baseada em consumo (km por litro)
class Carro extends Veiculo {
private double consumoLitrosPor100km; // ex.: 8.5 L/100km
public Carro(String id, double consumoLitrosPor100km) {
super(id);
this.consumoLitrosPor100km = consumoLitrosPor100km;
}
@Override
public void informacoes() {
System.out.println("=== Carro: " + id + " ===");
System.out.println("Consumo: " + consumoLitrosPor100km + " L/100km");
System.out.println("Eficiência medida em km/L (quanto maior, melhor).");
}
@Override
public void ativarSistema() {
System.out.println("Carro " + id + ": ligar ignição e sistemas eletrônicos.");
}
@Override
public void mover() {
System.out.println("Carro " + id + ": mover-se pela via.");
}
@Override
public void navegar() {
System.out.println("Carro " + id + ": navegando rota GPS.");
}
@Override
public double calcularEficiencia() {
// km por litro = 100 / (L por 100km)
return 100.0 / consumoLitrosPor100km;
}
}
// Drone: eficiência baseada em bateria (minutos restantes)
class Drone extends Veiculo {
private double autonomiaMinutosPorCarga; // minutos com bateria 100%
private double porcentagemBateria; // 0..100
public Drone(String id, double autonomiaMinutosPorCarga, double porcentagemBateria) {
super(id);
this.autonomiaMinutosPorCarga = autonomiaMinutosPorCarga;
this.porcentagemBateria = porcentagemBateria;
}
@Override
public void informacoes() {
System.out.println("=== Drone: " + id + " ===");
System.out.println("Autonomia por carga: " + autonomiaMinutosPorCarga + " minutos");
System.out.println("Bateria atual: " + porcentagemBateria + " %");
System.out.println("Eficiência medida em minutos de voo restantes.");
}
@Override
public void ativarSistema() {
System.out.println("Drone " + id + ": inicializando sensores e hélices.");
}
@Override
public void mover() {
System.out.println("Drone " + id + ": decolando e deslocando-se.");
}
@Override
public void navegar() {
System.out.println("Drone " + id + ": seguindo rota de navegação autônoma.");
}
@Override
public double calcularEficiencia() {
// minutos restantes = autonomia * (porcentagem / 100)
return autonomiaMinutosPorCarga * (porcentagemBateria / 100.0);
}
}
// Onibus: eficiência baseada em passageiros (passenger-km por litro)
class Onibus extends Veiculo {
private double consumoLitrosPor100km; // L/100km
private int passageiros;
public Onibus(String id, double consumoLitrosPor100km, int passageiros) {
super(id);
this.consumoLitrosPor100km = consumoLitrosPor100km;
this.passageiros = passageiros;
}
@Override
public void informacoes() {
System.out.println("=== Ônibus: " + id + " ===");
System.out.println("Consumo: " + consumoLitrosPor100km + " L/100km");
System.out.println("Passageiros a bordo: " + passageiros);
System.out.println("Eficiência medida em passenger-km por litro (quanto maior, melhor).");
}
@Override
public void ativarSistema() {
System.out.println("Ônibus " + id + ": verificando sistemas e doors.");
}
@Override
public void mover() {
System.out.println("Ônibus " + id + ": iniciando deslocamento pela rota.");
}
@Override
public void navegar() {
System.out.println("Ônibus " + id + ": seguindo rota programada.");
}
@Override
public double calcularEficiencia() {
// passenger-km per liter = passageiros * (100 / consumo L/100km)
return passageiros * (100.0 / consumoLitrosPor100km);
}
}
// CentralControle que guarda a lista de veículos e executa missões
class CentralControle {
private List<Veiculo> veiculos = new ArrayList<>();
public void adicionarVeiculo(Veiculo v) {
veiculos.add(v);
}
public void executarMissao() {
for (Veiculo v : veiculos) {
v.informacoes(); // polimórfico
v.ativarSistema(); // polimórfico
v.mover(); // polimórfico
v.navegar(); // polimórfico
double eficiencia = v.calcularEficiencia(); // polimórfico
System.out.printf("Eficiência calculada: %.2f%n", eficiencia);
System.out.println(); // linha em branco entre veículos
}
}
}
// Classe Main com exemplo de uso
public class Main {
public static void main(String[] args) {
CentralControle central = new CentralControle();
Carro c1 = new Carro("Carro-01", 8.5); // 8.5 L/100km -> ~11.76 km/L
Drone d1 = new Drone("Drone-Alpha", 30.0, 75.0); // 30 minutos por carga, 75% bateria -> 22.5 min
Onibus o1 = new Onibus("Onibus-100", 40.0, 50); // 40 L/100km, 50 passageiros -> 125 passenger-km/L
central.adicionarVeiculo(c1);
central.adicionarVeiculo(d1);
central.adicionarVeiculo(o1);
central.executarMissao();
}
}
Boa! Esse código mostra claramente polimorfismo:
CentralControle chama os mesmos métodos em referências do tipo Veiculo e cada classe concreta executa seu comportamento próprio e calcula sua própria eficiência. Se quiser, posso adaptar o exemplo para outra linguagem (Python, C#) ou adicionar mais métricas (por exemplo, normalizar todas as eficiências para uma unidade comum). Vai com calma — isso dá certo na prova se você explicar a métrica escolhida e lembrar que o polimorfismo resolve as chamadas em tempo de execução.