Serviço de Aluguel de Veículos
Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy — lição 87 de 87.
Para este desafio final, você construirá um sistema de Serviço de Aluguel de Veículos que reúne todos os conceitos de POO que você dominou ao longo deste curso.
Seu sistema deve modelar uma frota de diferentes tipos de veículos. Considere uma classe base Vehicle com propriedades comuns como placa, marca e valor da diária de aluguel. Subclasses como Car, Motorcycle e Truck podem estender isso com atributos específicos como número de assentos, cilindrada ou capacidade de carga.
Interfaces podem definir comportamentos de aluguel: uma interface Rentable pode declarar métodos como rent(), returnVehicle() e calculateCost(int days). Diferentes tipos de veículos podem implementar estratégias de precificação de forma distinta, tornando este um caso de uso perfeito para o polimorfismo.
Pense em como uma classe RentalAgency gerencia a frota usando composição.
Exceções personalizadas como VehicleNotAvailableException podem lidar com casos extremos.
Você pode aplicar o padrão Factory para criar veículos ou usar enums para categorias de veículos e status de aluguel.
Este desafio testa sua habilidade de projetar um sistema OOP completo e bem estruturado. Boa sorte!
Desafio
FácilVamos construir um Serviço de Aluguel de Veículos completo que reúne tudo o que você aprendeu sobre POO! Você criará um sistema que gerencia uma frota de diferentes tipos de veículos, lida com aluguéis com validação adequada e usa um padrão factory para criar veículos.
Você organizará seu código em sete arquivos:
RentalStatus.java: Crie um enum representando o status de aluguel de um veículo. Inclua os valoresAVAILABLE,RENTEDeMAINTENANCE. Adicione um campo privadodescription(String), um construtor e um getter.AVAILABLEdeve ter a descrição "ready to rent",RENTEDdeve ter "currently in use" eMAINTENANCEdeve ter "under service".VehicleNotAvailableException.java: Crie uma exceção personalizada que estendeException. O construtor deve aceitar uma placa (license plate) e criar uma mensagem no formatoVehicle not available: [licensePlate].Rentable.java: Crie uma interface definindo operações de aluguel. Declare os métodosrent()retornando um boolean,returnVehicle()retornando um boolean ecalculateCost(int days)retornando um double.Vehicle.java: Crie uma classe base abstrata para todos os veículos. Inclua campos privados paralicensePlate(String),brand(String),dailyRate(double) estatus(RentalStatus, inicializado comoAVAILABLE). O construtor recebelicensePlate,brandedailyRate. Inclua getters apropriados e um setter parastatus. Declare um método abstratogetVehicleType()retornando uma String. Implemente um métodogetDetails()que retorna"[licensePlate] [brand] ([vehicleType]) - $[dailyRate]/day - [status description]"comdailyRateformatado para 2 casas decimais.Car.java: Crie uma classe estendendoVehiclee implementandoRentable. Adicione um campo privadoseats(int). O construtor recebelicensePlate,brand,dailyRateeseats. ImplementegetVehicleType()para retornar"Car". Pararent(), se o status forAVAILABLE, defina-o comoRENTEDe retorne true; caso contrário, retorne false. ParareturnVehicle(), se o status forRENTED, defina-o comoAVAILABLEe retorne true; caso contrário, retorne false. ParacalculateCost(int days), retornedailyRatevezesdays.Motorcycle.java: Crie uma classe estendendoVehiclee implementandoRentable. Adicione um campo privadoengineCC(int). O construtor recebelicensePlate,brand,dailyRateeengineCC. ImplementegetVehicleType()para retornar"Motorcycle". Implemente os métodos deRentableda mesma forma que emCar, mascalculateCost()deve aplicar um desconto de 10% (multiplicar por 0.9).RentalAgency.java: Crie uma classe que gerencia a frota de veículos usando umArrayList. Inclua os métodos:addVehicle(Vehicle vehicle)- adiciona um veículo à frotafindVehicle(String licensePlate)- retorna oVehicleou nullrentVehicle(String licensePlate, int days)- encontra o veículo, tenta alugá-lo (fazendo o cast paraRentable) e retorna o custo do aluguel. LanceVehicleNotAvailableExceptionse o veículo não for encontrado ou serent()retornar falsereturnVehicle(String licensePlate)- encontra e devolve o veículo, retornando true em caso de sucessogetAvailableVehicles()- retorna umArrayListde veículos com statusAVAILABLE
Main.java: Construa seu serviço de aluguel! Você receberá uma string de comandos separados por vírgula:ADD_CAR:licensePlate:brand:dailyRate:seatsADD_MOTORCYCLE:licensePlate:brand:dailyRate:engineCCRENT:licensePlate:daysRETURN:licensePlateAVAILABLE
Processe cada comando e imprima:
- ADD_CAR/ADD_MOTORCYCLE:
Added: [brand] ([vehicleType]) - RENT:
Rented [licensePlate] for [days] days - Total: $[cost](custo com 2 decimais), ouError: [exception message] - RETURN:
Returned: [licensePlate]ouReturn failed: [licensePlate] - AVAILABLE: Imprima
Available vehicles:seguido pelos detalhes de cada veículo disponível em linhas separadas
Após todos os comandos, imprima
--- Fleet Summary ---seguido pelos detalhes de cada veículo.
Você receberá uma entrada: a string de comandos separados por vírgula.
Por exemplo, com a entrada ADD_CAR:ABC-123:Toyota:50.00:5,ADD_MOTORCYCLE:XYZ-789:Honda:40.00:600,RENT:ABC-123:3,RENT:ABC-123:2,AVAILABLE,RETURN:ABC-123, sua saída seria:
Added: Toyota (Car)
Added: Honda (Motorcycle)
Rented ABC-123 for 3 days - Total: $150.00
Error: Vehicle not available: ABC-123
Available vehicles:
XYZ-789 Honda (Motorcycle) - $40.00/day - ready to rent
Returned: ABC-123
--- Fleet Summary ---
ABC-123 Toyota (Car) - $50.00/day - ready to rent
XYZ-789 Honda (Motorcycle) - $40.00/day - ready to rentEste desafio combina herança (hierarquia de Vehicle), interfaces (Rentable), enums (RentalStatus), exceções personalizadas, polimorfismo (tratando diferentes tipos de veículos de forma uniforme) e composição (RentalAgency gerenciando veículos) em um sistema completo de serviço de aluguel!
Experimente você mesmo
import java.util.Scanner;
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
// TODO: Criar uma instância de RentalAgency
// TODO: Dividir a entrada por vírgula para obter comandos individuais
// TODO: Processar cada comando:
// ADD_CAR:licensePlate:brand:dailyRate:seats -> imprimir "Added: [brand] ([vehicleType])"
// ADD_MOTORCYCLE:licensePlate:brand:dailyRate:engineCC -> imprimir "Added: [brand] ([vehicleType])"
// RENT:licensePlate:days -> imprimir "Rented [licensePlate] for [days] days - Total: $[cost]" (2 casas decimais)
// ou "Error: [exception message]" se uma exceção for lançada
// RETURN:licensePlate -> imprimir "Returned: [licensePlate]" ou "Return failed: [licensePlate]"
// AVAILABLE -> imprimir "Available vehicles:" seguido pelos detalhes de cada veículo disponível
// TODO: Após todos os comandos, imprimir "--- Fleet Summary ---"
// seguido pelos detalhes de cada veículo
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave thisMétodosCampos (Atributos)Método ConstrutorSobrecarga de ConstrutorRecapitulação - Calculadora Simples4Herança
Herança Básica (extends)A Palavra-chave superSobrescrita de Método (@Override)Encadeamento de ConstrutoresA Classe ObjectHerança Simples e MultinívelPor que não há Herança Múltipla de ClassesRecapitulação - Hierarquia de Funcionários7Métodos Especiais e a Classe Object
Método toString()equals() e hashCode()Método clone()compareTo() e ComparableInterface ComparatorRecapitulação - Ordenação Personalizada2Modificadores de Acesso e Encapsulamento
Visão Geral dos Níveis de AcessoMétodos Getter e SetterOcultação de InformaçõesA Palavra-chave finalRecapitulação - Gerenciador de Conta Bancária5Polimorfismo
Fundamentos de Sobrecarga de MétodosSobrescrita de Métodos (Tempo de Execução)Upcasting e DowncastingO Operador instanceofClasses e Métodos AbstratosRecapitulação - Calculadora de Formas8Conceitos Avançados de OOP
Composição vs HerançaAgregação vs ComposiçãoClasses Internas, Aninhadas e AnônimasEnums e Métodos de EnumRecords (Java 16+)Classes Seladas (Java 17+)11Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão BuilderPadrão ObserverPadrão Strategy14Desafios Finais
Plataforma de E-LearningSistema BancárioDesenvolvimento de Personagens de JogosServiço de Aluguel de Veículos3Propriedades de Classe e Membros Estáticos
Variáveis de Instância vs EstáticasMétodos EstáticosBlocos EstáticosConstantes (static final)Recapitulação - Contador e Utilitário6Interfaces e Classes Abstratas
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesDefault e Static em InterfacesClasses Abstratas vs InterfacesInterfaces FuncionaisRecapitulação - Sistema de Pagamento9Generics
Introdução a GenericsClasses GenéricasMétodos GenéricosParâmetros de Tipos DelimitadosWildcards (?, extends, super)Recapitulação - Container Genérico12Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão Iterator