Fahrzeugvermietungsdienst
Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy. Lektion 87 von 87.
Für diese abschließende Herausforderung entwickelst du ein Fahrzeugvermietungssystem, das alle OOP-Konzepte vereint, die du im Laufe dieses Kurses gemeistert hast.
Dein System sollte eine Flotte verschiedener Fahrzeugtypen modellieren. Betrachte eine Basisklasse Vehicle mit gemeinsamen Eigenschaften wie Kennzeichen, Marke und täglichem Mietpreis. Unterklassen wie Car, Motorcycle und Truck können diese um spezifische Attribute wie Sitzplatzanzahl, Hubraum oder Ladekapazität erweitern.
Schnittstellen können Mietverhalten definieren: Eine Rentable-Schnittstelle könnte Methoden wie rent(), returnVehicle() und calculateCost(int days) deklarieren. Verschiedene Fahrzeugtypen könnten Preisstrategien unterschiedlich umsetzen, was dies zu einem idealen Anwendungsfall für Polymorphie macht.
Überlege, wie eine Klasse RentalAgency den Fuhrpark mithilfe von Komposition verwaltet.
Benutzerdefinierte Ausnahmen wie VehicleNotAvailableException können Sonderfälle behandeln.
Du könntest das Factory-Muster verwenden, um Fahrzeuge zu erstellen, oder Enums für Fahrzeugkategorien und den Mietstatus nutzen.
Diese Herausforderung prüft, ob du ein vollständiges, gut strukturiertes OOP-System entwerfen kannst. Viel Erfolg!
Aufgabe
EinfachBauen wir einen vollständigen Fahrzeugverleih, der alles zusammenführt, was du über OOP gelernt hast! Du erstellst ein System, das einen Fuhrpark mit verschiedenen Fahrzeugtypen verwaltet, Vermietungen mit geeigneter Validierung abwickelt und ein Factory-Pattern zum Erstellen von Fahrzeugen verwendet.
Du organisierst deinen Code über sieben Dateien:
RentalStatus.java: Erstelle ein Enum, das den Mietstatus eines Fahrzeugs darstellt. Füge die WerteAVAILABLE,RENTEDundMAINTENANCEhinzu. Ergänze ein privates Felddescription(String), einen Konstruktor und einen Getter. Für Available soll die Beschreibung "ready to rent" lauten, für rented "currently in use" und für maintenance "under service".VehicleNotAvailableException.java: Erstelle eine benutzerdefinierte Exception, dieExceptionerweitert. Der Konstruktor soll ein Kennzeichen entgegennehmen und eine Nachricht im FormatVehicle not available: [licensePlate]erstellen.Rentable.java: Erstelle ein Interface, das Vermietungsvorgänge definiert. Deklariere die Methodenrent(), die einen boolean zurückgibt,returnVehicle(), die einen boolean zurückgibt, undcalculateCost(int days), die einen double zurückgibt.Vehicle.java: Erstelle eine abstrakte Basisklasse für alle Fahrzeuge. Füge private Felder fürlicensePlate(String),brand(String),dailyRate(double) undstatus(RentalStatus, initialisiert mit AVAILABLE) hinzu. Der Konstruktor nimmt licensePlate, brand und dailyRate entgegen. Ergänze passende Getter und einen Setter für status. Deklariere eine abstrakte MethodegetVehicleType(), die einen String zurückgibt. Implementiere eine MethodegetDetails(), die"[licensePlate] [brand] ([vehicleType]) - $[dailyRate]/day - [status description]"zurückgibt, wobei dailyRate auf 2 Dezimalstellen formatiert ist.Car.java: Erstelle eine Klasse, die Vehicle erweitert und Rentable implementiert. Füge ein privates Feldseats(int) hinzu. Der Konstruktor nimmt licensePlate, brand, dailyRate und seats entgegen. ImplementieregetVehicleType()so, dass die Methode"Car"zurückgibt. Wenn der Status beirent()AVAILABLE ist, setze ihn auf RENTED und gib true zurück; andernfalls gib false zurück. Wenn der Status beireturnVehicle()RENTED ist, setze ihn auf AVAILABLE und gib true zurück; andernfalls gib false zurück. Gib beicalculateCost(int days)dailyRate multipliziert mit days zurück.Motorcycle.java: Erstelle eine Klasse, die Vehicle erweitert und Rentable implementiert. Füge ein privates FeldengineCC(int) hinzu. Der Konstruktor nimmt licensePlate, brand, dailyRate und engineCC entgegen. ImplementieregetVehicleType()so, dass die Methode"Motorcycle"zurückgibt. Implementiere die Rentable-Methoden genauso wie bei Car, abercalculateCost()soll einen Rabatt von 10 % anwenden (mit 0.9 multiplizieren).RentalAgency.java: Erstelle eine Klasse, die den Fuhrpark mithilfe einer ArrayList verwaltet. Füge folgende Methoden hinzu:addVehicle(Vehicle vehicle)– fügt dem Fuhrpark ein Fahrzeug hinzufindVehicle(String licensePlate)– gibt das Vehicle oder null zurückrentVehicle(String licensePlate, int days)– sucht das Fahrzeug, versucht, es zu vermieten (mit einer Umwandlung in Rentable), und gibt die Mietkosten zurück. WirfVehicleNotAvailableException, wenn das Fahrzeug nicht gefunden wird oder rent() false zurückgibtreturnVehicle(String licensePlate)– sucht das Fahrzeug und gibt es zurück; bei Erfolg wird true zurückgegebengetAvailableVehicles()– gibt eine ArrayList mit Fahrzeugen zurück, deren Status AVAILABLE ist
Main.java: Baue deinen Fahrzeugverleih! Du erhältst eine durch Kommas getrennte Zeichenfolge mit Befehlen:ADD_CAR:licensePlate:brand:dailyRate:seatsADD_MOTORCYCLE:licensePlate:brand:dailyRate:engineCCRENT:licensePlate:daysRETURN:licensePlateAVAILABLE
Verarbeite jeden Befehl und gib Folgendes aus:
- ADD_CAR/ADD_MOTORCYCLE:
Added: [brand] ([vehicleType]) - RENT:
Rented [licensePlate] for [days] days - Total: $[cost](Kosten mit 2 Dezimalstellen) oderError: [exception message] - RETURN:
Returned: [licensePlate]oderReturn failed: [licensePlate] - AVAILABLE: Gib
Available vehicles:aus, gefolgt von den Details jedes verfügbaren Fahrzeugs in separaten Zeilen
Gib nach allen Befehlen
--- Fleet Summary ---aus, gefolgt von den Details jedes Fahrzeugs.
Du erhältst eine Eingabe: die durch Kommas getrennte Befehlszeichenfolge.
Bei der Eingabe 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 wäre deine Ausgabe beispielsweise:
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 rentDiese Herausforderung verbindet Vererbung (Vehicle-Hierarchie), Interfaces (Rentable), Enums (RentalStatus), benutzerdefinierte Exceptions, Polymorphismus (verschiedene Fahrzeugtypen einheitlich behandeln) und Komposition (RentalAgency verwaltet Fahrzeuge) zu einem vollständigen Fahrzeugverleihsystem!
Probier es selbst
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: Eine RentalAgency-Instanz erstellen
// TODO: Die Eingabe an den Kommas aufteilen, um die einzelnen Befehle zu erhalten
// TODO: Jeden Befehl verarbeiten:
// ADD_CAR:licensePlate:brand:dailyRate:seats -> "Added: [brand] ([vehicleType])" ausgeben
// ADD_MOTORCYCLE:licensePlate:brand:dailyRate:engineCC -> "Added: [brand] ([vehicleType])" ausgeben
// RENT:licensePlate:days -> "Rented [licensePlate] for [days] days - Total: $[cost]" ausgeben (mit 2 Dezimalstellen)
// oder "Error: [exception message]", falls eine Exception ausgelöst wird
// RETURN:licensePlate -> "Returned: [licensePlate]" oder "Return failed: [licensePlate]" ausgeben
// AVAILABLE -> "Available vehicles:" ausgeben, gefolgt von den Details jedes verfügbaren Fahrzeugs
// TODO: Nach allen Befehlen "--- Fleet Summary ---" ausgeben
// gefolgt von den Details jedes Fahrzeugs
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas Schlüsselwort thisMethodenFelder (Attribute)KonstruktormethodeÜberladen von KonstruktorenRückblick – Einfacher Taschenrechner4Vererbung
Grundlegende Vererbung (extends)Das Schlüsselwort superÜberschreiben von Methoden (@Override)KonstruktorverkettungDie Object-KlasseEinfach- und mehrstufige VererbungWarum keine Mehrfachvererbung von KlassenRückblick – Mitarbeiterhierarchie7Spezielle Methoden & Object-Klasse
toString()-Methodeequals() und hashCode()clone()-MethodecompareTo() und ComparableComparator-SchnittstelleRückblick – Benutzerdefinierte Sortierung2Zugriffsmodifikatoren & Kapselung
Übersicht der ZugriffsebenenGetter- und Setter-MethodenInformationsverbergungDas Schlüsselwort finalRückblick – Bankkontoverwaltung5Polymorphismus
Grundlagen der MethodenüberladungMethodenüberschreibung (Laufzeit)Upcasting und DowncastingDer instanceof-OperatorAbstrakte Klassen und MethodenRückblick – Formrechner8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungAggregation vs. KompositionInnere, verschachtelte & anonyme KlassenEnums und Enum-MethodenRecords (Java 16+)Versiegelte Klassen (Java 17+)11Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterBuilder-MusterObserver-MusterStrategie-Muster14Abschließende Herausforderungen
E-Learning-PlattformBankingsystemEntwicklung einer SpielfigurFahrzeugvermietungsdienst3Klassen-Props & statische Member
Instanz- vs. statische VariablenStatische MethodenStatische BlöckeKonstanten (static final)Wiederholung – Counter & Utility6Schnittstellen & abstrakte Klassen
Einführung in InterfacesInterfaces implementierenMehrere Interfaces implementierenDefault & Static in InterfacesAbstrakte Klassen vs. InterfacesFunktionale InterfacesRückblick – ZahlungssystemÜbe selbstständig: Online-Java-Compiler