1 . O sistema deve ser orientado a objetos e atender aos seguintes requisitos:
- Classe abstrata Veiculo
◯ Atributos:
- modelo (String)
- ano (int)
- Métodos:
- informacoes() (concreto): imprime modelo e ano.
- mover() (abstrato): descreve como o veículo se desloca.
- Classe abstrata Autonomo
- Representa veículos com capacidade de condução autônoma.
- Método abstrato: navegar() (define como o vésculo escolhe rotas).
- Método concreto: ativarSistema() imprimę “Sistema autônomo ativado!”.
- Classes concretas que herdam de ambas (herança múltipla indireta via interfaces ou classes abstratas)
- Impla mover() imprimindo “O carro dirige pelas ruas.”.
- CarroAutonomo
- Implementa navegar() imprimindo "O carro usa GPS para
- DroneAutonomo
- Implementa mover() imprimindo “O drone voa pelos céus.” . traçar rotas."
- Implementa navegar() imprimindo “O drone usa sensores. para evitar obstáculos.”.
- Onibusautonomo
- Implementa mover() imprimindo "O ônibus segue pelas
- Implementa navegar() imprimindo “O ônibus otimiza rotas avenidas.”. para passageiros."
◯ Atributos:
Passo 1
Vou listar claramente o que o enunciado pede e quais informações foram dadas (sem resolver ainda):
- É exigido um sistema orientado a objetos com as seguintes entidades:
- Uma classe abstrata chamada Veiculo
- Atributos:
- modelo (String)
- ano (int)
- Métodos:
- informacoes() — método concreto que imprime modelo e ano.
- mover() — método abstrato que descreve como o veículo se desloca.
- Atributos:
- Uma entidade abstrata chamada Autonomo (representa veículos com capacidade autônoma)
- Método abstrato navegar() — define como o veículo escolhe rotas.
- Método concreto ativarSistema() — imprime “Sistema autônomo ativado!”.
- Três classes concretas que combinam Veiculo e Autonomo (herança múltipla indireta):
- CarroAutonomo
- Deve implementar mover() imprimindo “O carro dirige pelas ruas.”
- Deve implementar navegar() imprimindo “O carro usa GPS para traçar rotas.”
- DroneAutonomo
- Deve implementar mover() imprimindo “O drone voa pelos céus.”
- Deve implementar navegar() imprimindo “O drone usa sensores para evitar obstáculos.”
- OnibusAutonomo
- Deve implementar mover() imprimindo “O ônibus segue pelas avenidas.”
- Deve implementar navegar() imprimindo “O ônibus otimiza rotas para passageiros.”
- CarroAutonomo
- Uma classe abstrata chamada Veiculo
- O enunciado pede que a herança múltipla seja feita indiretamente (por exemplo via interfaces ou classes abstratas), e que os métodos concretos imprimam as frases indicadas.
Passo 2
Escolha da linguagem e justificativa:
- Vou usar a linguagem Java para implementar o sistema. Por quê?
- O enunciado usa termos como
Stringeint, e fala explicitamente em “classe abstrata”, “herança”, etc., que combinam bem com Java. - Em Java não é permitido estender duas classes concretas/abstratas ao mesmo tempo (ou seja, sem suporte direto à herança múltipla de classes). Mas Java permite implementar várias interfaces. Desde Java 8 interfaces podem conter métodos
default(com implementação), o que resolve a exigência de um método concreto (ativarSistema()) junto com método abstrato (navegar()).
- O enunciado usa termos como
- Conclusão: Vou criar
abstract class Veiculoeinterface Autonomo(comvoid navegar();abstrato e umdefault void ativarSistema()concreto). As classes concretasCarroAutonomo,DroneAutonomoeOnibusAutonomovãoextends Veiculo implements Autonomo.
Passo 3
Noções e conceitos que vamos usar (explicando como se eu estivesse no seu lugar):
- Classe abstrata:
- É uma classe que pode conter métodos concretos (com corpo) e métodos abstratos (sem corpo).
- Não pode ser instanciada diretamente; serve de “molde” para subclasses que implementem os métodos abstratos.
- Interface (em Java 8+):
- Normalmente define métodos abstratos que a classe implementadora deve definir.
- Pode ter métodos
defaultcom implementação. Isso permite colocarativarSistema()com implementação dentro de uma interfaceAutonomo.
- Herança simples + interface = herança múltipla indireta:
- Em Java uma classe estende no máximo uma outra classe, mas pode implementar várias interfaces. Assim conseguimos combinar comportamento comum (Veiculo) com comportamento autônomo (Autonomo).
- Polimorfismo:
- Um objeto de
CarroAutonomopode ser referenciado tanto comoVeiculoquanto comoAutonomo. Isso permite escrever código genérico (por exemplo, uma lista deVeiculoou uma lista deAutonomo) e chamar métodos específicos conforme o tipo.
- Um objeto de
- Override:
- Quando uma subclasse fornece a implementação do método abstrato definido na superclasse ou interface, dizemos que ela “sobrescreve” (override) o método. Em Java usamos a anotação
@Overridepara indicar isso, o que ajuda a evitar erros.
- Quando uma subclasse fornece a implementação do método abstrato definido na superclasse ou interface, dizemos que ela “sobrescreve” (override) o método. Em Java usamos a anotação
Passo 4
Projeto da API (assinaturas e decisões):
abstract class Veiculo- Atributos privados
modelo(String) eano(int). - Construtor para inicializar
modeloeano. - Método concreto
informacoes()que imprime o modelo e o ano de forma legível. - Método abstrato
mover()(assinaturapublic abstract void mover();).
- Atributos privados
interface Autonomo- Método abstrato
void navegar(); - Método concreto
default void ativarSistema()que imprimeSistema autônomo ativado!
- Método abstrato
- Subclasses
CarroAutonomo,DroneAutonomo,OnibusAutonomo- Cada uma
extends Veiculo implements Autonomo - Implementam
mover()enavegar()com as frases que o enunciado pediu. - Cada subclasse terá um construtor que chama
super(modelo, ano).
- Cada uma
Passo 5
Escrevendo o código passo a passo (explicando cada bloco):
- Veiculo:
- Porquê usar atributos privados? Para encapsulamento: assim forçamos o acesso via métodos (aqui
informacoes()). - O método
informacoes()vai fazerSystem.out.println("Modelo: " + modelo + ", Ano: " + ano);. mover()é abstrato porque cada veículo se move de forma diferente.
- Porquê usar atributos privados? Para encapsulamento: assim forçamos o acesso via métodos (aqui
- Autonomo (interface):
void navegar();é o contrato que diz “quem implementa Autonomo precisa definir como navegar”.default void ativarSistema()fornece implementação padrão para ativar o sistema autônomo que todas as classes herdarão sem precisar reescrever.- Isso resolve a necessidade de “método abstrato” + “método concreto” na mesma entidade representando autonomia.
- Subclasses:
- Cada subclasse implementa
mover()enavegar()conforme solicitado. Usar@Overrideajuda o compilador a garantir que a assinatura está correta. - Exemplo do corpo de
mover()em CarroAutonomo:System.out.println("O carro dirige pelas ruas."); - Exemplo do corpo de
navegar()em CarroAutonomo:System.out.println("O carro usa GPS para traçar rotas.");
- Cada subclasse implementa
Passo 6
Exemplo de uso (o que deve acontecer quando rodar):
- Criar instâncias de
CarroAutonomo,DroneAutonomo,OnibusAutonomo. - Para cada instância:
- Chamar
informacoes()— deve imprimir o modelo e o ano. - Chamar
ativarSistema()— deve imprimirSistema autônomo ativado!. - Chamar
mover()— imprime o deslocamento do tipo de veículo. - Chamar
navegar()— imprime como o veículo escolhe/traça rotas.
- Chamar
- Isso demonstra polimorfismo e que a implementação está correta.
Passo 7
Cuidados e erros comuns que evitamos:
- Não esquecer de implementar todos os métodos abstratos; caso contrário a subclasse precisa ser declarada
abstract. - Em Java não usar acentos em nomes de identificadores (por exemplo, evitar
Autônomocomo nome de interface). UsarAutonomo. - Garantir que
ativarSistema()foi colocado comodefaulteminterface Autonomo(ou, alternativamente, usar uma classe abstrata Autonomo e reestruturar, mas aí não seria possível estenderVeiculoeAutonomoao mesmo tempo). - Usar
@Overridepara ajudar a detectar erros de assinatura.
Passo 8
Motivação didática final (como aplicar isso na prova):
- Se te pedirem “implemente herança múltipla indireta” em Java, pense sempre “uma classe abstrata para a hierarquia de dados/comportamento comum + interfaces para capacidades extras”.
- Lembre-se: interfaces podem conter implementações (
default) — isso permite misturar método abstrato e método concreto num mesmo contrato, igual ao enunciado pediu. - Na prova, identifique o que é comportamento comum (vai para a classe abstrata) e o que é capacidade que pode ser misturada em vários tipos (vai para interface).
Resposta
public class Main {
public static void main(String[] args) {
CarroAutonomo carro = new CarroAutonomo("Sedan X", 2022);
DroneAutonomo drone = new DroneAutonomo("Drone Z", 2024);
OnibusAutonomo onibus = new OnibusAutonomo("Ônibus Urbano", 2021);
// Carro
carro.informacoes();
carro.ativarSistema();
carro.mover();
carro.navegar();
System.out.println();
// Drone
drone.informacoes();
drone.ativarSistema();
drone.mover();
drone.navegar();
System.out.println();
// Ônibus
onibus.informacoes();
onibus.ativarSistema();
onibus.mover();
onibus.navegar();
}
// Classe abstrata Veiculo
public static abstract class Veiculo {
private String modelo;
private int ano;
public Veiculo(String modelo, int ano) {
this.modelo = modelo;
this.ano = ano;
}
public void informacoes() {
System.out.println("Modelo: " + modelo + ", Ano: " + ano);
}
public abstract void mover();
}
// Interface Autonomo (com método abstrato e método concreto via default)
public interface Autonomo {
void navegar();
default void ativarSistema() {
System.out.println("Sistema autônomo ativado!");
}
}
// CarroAutonomo
public static class CarroAutonomo extends Veiculo implements Autonomo {
public CarroAutonomo(String modelo, int ano) {
super(modelo, ano);
}
@Override
public void mover() {
System.out.println("O carro dirige pelas ruas.");
}
@Override
public void navegar() {
System.out.println("O carro usa GPS para traçar rotas.");
}
}
// DroneAutonomo
public static class DroneAutonomo extends Veiculo implements Autonomo {
public DroneAutonomo(String modelo, int ano) {
super(modelo, ano);
}
@Override
public void mover() {
System.out.println("O drone voa pelos céus.");
}
@Override
public void navegar() {
System.out.println("O drone usa sensores para evitar obstáculos.");
}
}
// OnibusAutonomo
public static class OnibusAutonomo extends Veiculo implements Autonomo {
public OnibusAutonomo(String modelo, int ano) {
super(modelo, ano);
}
@Override
public void mover() {
System.out.println("O ônibus segue pelas avenidas.");
}
@Override
public void navegar() {
System.out.println("O ônibus otimiza rotas para passageiros.");
}
}
}