Fahrzeugvermietung
Teil des Abschnitts Objektorientierte Programmierung der C#-Journey von Coddy — Lektion 70 von 70.
Aufgabe
EinfachLassen Sie uns einen Fahrzeugvermietungsservice aufbauen, der Vererbung, Schnittstellen und das Strategy-Muster vereint! Sie erstellen ein System, in dem verschiedene Fahrzeugtypen mit flexiblen Preisstrategien gemietet werden können – dies zeigt, wie OOP wartbare und erweiterbare Geschäftslogik ermöglicht.
Sie werden Ihren Code in sechs Dateien organisieren:
Vehicle.cs: Erstellen Sie Ihre Fahrzeughierarchie im NamespaceRental.Models. Die BasisklasseVehiclesollte schreibgeschützte Eigenschaften fürLicensePlateundBrand, eineDailyRate(decimal) und eine EigenschaftIsAvailablemit einem privaten Setter haben, der über die MethodenMarkAsRented()undMarkAsReturned()gesteuert wird. Erstellen Sie dann drei abgeleitete Klassen:Carmit einer EigenschaftSeats,Motorcyclemit einer EigenschaftEngineCCundTruckmit einer EigenschaftCargoCapacity(decimal). Jede abgeleitete Klasse sollte den Basis-Konstruktor aufrufen und ihre spezifische Eigenschaft setzen.IPricingStrategy.cs: Definieren Sie das InterfaceIPricingStrategyim NamespaceRental.Pricingmit einer einzigen MethodeCalculatePrice(Vehicle vehicle, int days), die einen decimal-Wert zurückgibt.PricingStrategies.cs: Implementieren Sie zwei Preisstrategien im NamespaceRental.Pricing.StandardPricingmultipliziert einfach die Tagesrate des Fahrzeugs mit der Anzahl der Tage.WeekendDiscountPricinggewährt einen Rabatt von 10 % (Multiplikation mit 0.9), wenn die Miete 2 oder mehr Tage beträgt, andernfalls wird die Standardberechnung verwendet.RentalRecord.cs: Erstellen Sie eine KlasseRentalim NamespaceRental.Models, um Vermietungen zu verfolgen. Sie sollte schreibgeschützte Eigenschaften fürCustomerName(string),Vehicle(Vehicle),Days(int) undTotalPrice(decimal) haben, die alle über den Konstruktor gesetzt werden.RentalService.cs: Erstellen Sie eine KlasseRentalServiceim NamespaceRental.Services, die die Flotte verwaltet und Vermietungen verarbeitet. Sie erhält eineIPricingStrategyüber ihren Konstruktor (Dependency Injection). Implementieren Sie:AddVehicle(Vehicle vehicle)– fügt ein Fahrzeug zur Flotte hinzuRentVehicle(string customerName, string licensePlate, int days)– gibt einRental-Objekt zurück, wenn das Fahrzeug existiert und verfügbar ist, andernfallsnull. Denken Sie daran, das Fahrzeug als vermietet zu markieren und den Preis mit der injizierten Strategie zu berechnen.ReturnVehicle(string licensePlate)– markiert das Fahrzeug als verfügbar und gibttruezurück, wenn dies erfolgreich warGetAvailableVehicles()– gibt eine Liste aller verfügbaren Fahrzeuge zurück
Program.cs: Führen Sie alles zusammen, indem Sie Fahrzeuge erstellen, den Service mit einer Preisstrategie einrichten und Vermietungsvorgänge basierend auf der Eingabe verarbeiten.
Sie erhalten die folgenden Eingaben:
- Zu verwendende Preisstrategie (
standardoderweekend) - Anzahl der hinzuzufügenden Fahrzeuge
- Für jedes Fahrzeug: Typ (
car,motorcycleodertruck), Kennzeichen, Marke, Tagesrate und typspezifischer Wert (Sitze, Hubraum oder Ladekapazität) - Anzahl der auszuführenden Operationen
- Für jede Operation: die Aktion gefolgt von den relevanten Daten
Operationsformate:
rent
{customerName}
{licensePlate}
{days}
return
{licensePlate}
availableAusgabeformate:
- Miete erfolgreich:
Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice} - Miete fehlgeschlagen:
Rental failed: {licensePlate} - Rückgabe erfolgreich:
Returned: {licensePlate} - Rückgabe fehlgeschlagen:
Return failed: {licensePlate} - Verfügbar: Geben Sie jedes verfügbare Fahrzeug als
{Type}: {Brand} ({LicensePlate}) - {DailyRate}/dayaus, wobei Type "Car", "Motorcycle" oder "Truck" ist
Wenn die Eingaben beispielsweise wie folgt lauten:
weekend
3
car
ABC-123
Toyota
50
5
motorcycle
XYZ-789
Honda
30
600
truck
TRK-001
Ford
80
2000
5
available
rent
Alice
ABC-123
3
rent
Bob
ABC-123
2
available
return
ABC-123Sollte die Ausgabe wie folgt aussehen:
Car: Toyota (ABC-123) - 50/day
Motorcycle: Honda (XYZ-789) - 30/day
Truck: Ford (TRK-001) - 80/day
Rented: Toyota (ABC-123) to Alice for 3 days - Total: 135.0
Rental failed: ABC-123
Motorcycle: Honda (XYZ-789) - 30/day
Truck: Ford (TRK-001) - 80/day
Returned: ABC-123Beachten Sie, wie die Preisstrategie in den Service injiziert wird – Sie könnten StandardPricing problemlos gegen WeekendDiscountPricing austauschen, ohne den Code von RentalService überhaupt zu ändern. Dies ist die Stärke des Strategy-Musters in Kombination mit Dependency Injection!
Probier es selbst
using System;
using System.Collections.Generic;
using Rental.Models;
using Rental.Pricing;
using Rental.Services;
class Program
{
public static void Main(string[] args)
{
// Preistyp der Strategie lesen
string strategyType = Console.ReadLine();
// TODO: Erstelle die passende Preisstrategie basierend auf der Eingabe
// "standard" -> StandardPricing
// "weekend" -> WeekendDiscountPricing
IPricingStrategy strategy = null; // TODO: Basierend auf strategyType initialisieren
// TODO: RentalService mit der Preisstrategie erstellen
// Anzahl der Fahrzeuge lesen
int vehicleCount = Convert.ToInt32(Console.ReadLine());
// TODO: Jedes Fahrzeug lesen und zum Service hinzufügen
// Für jedes Fahrzeug lesen:
// - Typ (car, motorcycle, truck)
// - Kennzeichen
// - Marke
// - Tagesrate
// - typspezifischer Wert (seats, engineCC oder cargo capacity)
// Anzahl der Operationen lesen
int operationCount = Convert.ToInt32(Console.ReadLine());
// TODO: Jede Operation verarbeiten
// Operationen: rent, return, available
//
// Für "rent":
// customerName, licensePlate, days lesen
// Ausgabe: "Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice}"
// Oder: "Rental failed: {licensePlate}"
//
// Für "return":
// licensePlate lesen
// Ausgabe: "Returned: {licensePlate}" oder "Return failed: {licensePlate}"
//
// Für "available":
// Gib jedes verfügbare Fahrzeug wie folgt aus:
// "{Type}: {Brand} ({LicensePlate}) - {DailyRate}/day"
}
}
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienNamespaces & DirektivenEinführung in Klassen & ObjekteDas 'this'-SchlüsselwortMethoden und ParameterFelder vs. EigenschaftenKonstruktorenObjekt-InitialisiererZusammenfassung - Einfacher Taschenrechner4Vererbung
Grundlagen der Vererbung (:) SyntaxDas 'base'-SchlüsselwortVirtual & Override SchlüsselwörterVersiegelte KlassenDie 'object'-BasisklasseZusammenfassung – Mitarbeiter-Hierarchie7Fortgeschrittene Funktionen
OperatorüberladungIndexer (this[])ToString() überschreibenErweiterungsmethodenZusammenfassung - Benutzerdefinierte Liste2Eigenschaften & Statische Member
Automatisch implementierte EigenschaftenRead-Only- & Write-Only-EigenschaftenStatische Felder & MethodenStatische KlassenExpression-Bodied Member5Polymorphismus & Interfaces
Compile- vs. Runtime-PolymorphismusInterface vs. abstrakte KlasseMehrfache InterfacesExplizite InterfacesUpcasting & DowncastingRecap – Shape Calculator3Klassenarchitektur
Instanz- vs. statische Daten'readonly' & 'const' SchlüsselwörterBacking FieldsZusammenfassung - Bankkonto-Manager6Kapselung
ZugriffsmodifikatorenProperties zur KapselungImplementierung von Data HidingImmutability-MusterRückblick – Studierendendaten