Menu
Coddy logo textTech

Wypożyczalnia pojazdów

Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 87 z 87.

W tym ostatnim wyzwaniu zbudujesz system wypożyczalni pojazdów, który łączy wszystkie poznane przez Ciebie koncepcje programowania obiektowego.

Twój system powinien modelować flotę pojazdów różnych typów. Rozważ klasę bazową Vehicle ze wspólnymi właściwościami, takimi jak numer rejestracyjny, marka i dzienna stawka za wynajem. Podklasy, takie jak Car, Motorcycle i Truck, mogą ją rozszerzać o specyficzne atrybuty, takie jak liczba miejsc, pojemność silnika lub ładowność.

Interfejsy mogą definiować zachowania związane z wynajmem: interfejs Rentable może deklarować metody takie jak rent(), returnVehicle() i calculateCost(int days). Różne typy pojazdów mogą implementować strategie cenowe na różne sposoby, co czyni to doskonałym zastosowaniem polimorfizmu.

Zastanów się, jak klasa RentalAgency zarządza flotą za pomocą kompozycji.

Niestandardowe wyjątki, takie jak VehicleNotAvailableException, mogą obsługiwać przypadki brzegowe.

Możesz zastosować wzorzec Factory do tworzenia pojazdów lub użyć typów wyliczeniowych dla kategorii pojazdów i statusu wypożyczenia.

To wyzwanie sprawdza Twoją umiejętność zaprojektowania kompletnego, dobrze ustrukturyzowanego systemu OOP. Powodzenia!

challenge icon

Wyzwanie

Łatwy

Zbudujmy kompletny system wypożyczalni pojazdów, który łączy wszystko, czego nauczyłeś się o OOP! Utworzysz system zarządzający flotą różnych typów pojazdów, obsługujący wypożyczenia z odpowiednią walidacją i wykorzystujący wzorzec fabryki do tworzenia pojazdów.

Rozmieścisz swój kod w siedmiu plikach:

  • RentalStatus.java: Utwórz enum reprezentujący status wypożyczenia pojazdu. Uwzględnij wartości AVAILABLE, RENTED i MAINTENANCE. Dodaj prywatne pole description (String), konstruktor i getter. Status dostępności powinien mieć opis "ready to rent", status wypożyczenia — "currently in use", a status konserwacji — "under service".
  • VehicleNotAvailableException.java: Utwórz własny wyjątek rozszerzający Exception. Konstruktor powinien przyjmować numer rejestracyjny i tworzyć komunikat w formacie Vehicle not available: [licensePlate].
  • Rentable.java: Utwórz interfejs definiujący operacje wypożyczania. Zadeklaruj metody rent() zwracającą wartość logiczną, returnVehicle() zwracającą wartość logiczną oraz calculateCost(int days) zwracającą wartość typu double.
  • Vehicle.java: Utwórz abstrakcyjną klasę bazową dla wszystkich pojazdów. Uwzględnij prywatne pola: licensePlate (String), brand (String), dailyRate (double) i status (RentalStatus, zainicjowany wartością AVAILABLE). Konstruktor przyjmuje licensePlate, brand i dailyRate. Dodaj odpowiednie gettery oraz setter dla statusu. Zadeklaruj metodę abstrakcyjną getVehicleType() zwracającą wartość typu String. Zaimplementuj metodę getDetails(), która zwraca "[licensePlate] [brand] ([vehicleType]) - $[dailyRate]/day - [status description]", przy czym dailyRate ma być sformatowane do 2 miejsc po przecinku.
  • Car.java: Utwórz klasę rozszerzającą Vehicle i implementującą Rentable. Dodaj prywatne pole seats (int). Konstruktor przyjmuje licensePlate, brand, dailyRate i seats. Zaimplementuj getVehicleType(), aby zwracała "Car". W metodzie rent(), jeśli status ma wartość AVAILABLE, ustaw go na RENTED i zwróć true; w przeciwnym razie zwróć false. W metodzie returnVehicle(), jeśli status ma wartość RENTED, ustaw go na AVAILABLE i zwróć true; w przeciwnym razie zwróć false. Metoda calculateCost(int days) powinna zwracać iloczyn dailyRate i days.
  • Motorcycle.java: Utwórz klasę rozszerzającą Vehicle i implementującą Rentable. Dodaj prywatne pole engineCC (int). Konstruktor przyjmuje licensePlate, brand, dailyRate i engineCC. Zaimplementuj getVehicleType(), aby zwracała "Motorcycle". Zaimplementuj metody interfejsu Rentable tak samo jak w klasie Car, ale metoda calculateCost() powinna uwzględniać 10% rabatu (pomnożyć wynik przez 0.9).
  • RentalAgency.java: Utwórz klasę zarządzającą flotą pojazdów za pomocą ArrayList. Dodaj metody:
    • addVehicle(Vehicle vehicle) — dodaje pojazd do floty
    • findVehicle(String licensePlate) — zwraca obiekt Vehicle albo null
    • rentVehicle(String licensePlate, int days) — wyszukuje pojazd, próbuje go wypożyczyć (rzutując typ na Rentable) i zwraca koszt wypożyczenia. Zgłasza VehicleNotAvailableException, jeśli pojazd nie zostanie znaleziony lub jeśli rent() zwróci false
    • returnVehicle(String licensePlate) — wyszukuje i zwraca pojazd, zwracając true w przypadku powodzenia
    • getAvailableVehicles() — zwraca ArrayList pojazdów ze statusem AVAILABLE
  • Main.java: Zbuduj system wypożyczalni! Otrzymasz rozdzielony przecinkami ciąg poleceń:
    • ADD_CAR:licensePlate:brand:dailyRate:seats
    • ADD_MOTORCYCLE:licensePlate:brand:dailyRate:engineCC
    • RENT:licensePlate:days
    • RETURN:licensePlate
    • AVAILABLE

    Przetwórz każde polecenie i wypisz:

    • ADD_CAR/ADD_MOTORCYCLE: Added: [brand] ([vehicleType])
    • RENT: Rented [licensePlate] for [days] days - Total: $[cost] (koszt z dokładnością do 2 miejsc po przecinku) lub Error: [exception message]
    • RETURN: Returned: [licensePlate] lub Return failed: [licensePlate]
    • AVAILABLE: Wypisz Available vehicles:, a następnie szczegóły każdego dostępnego pojazdu, każdy w osobnym wierszu

    Po przetworzeniu wszystkich poleceń wypisz --- Fleet Summary ---, a następnie szczegóły każdego pojazdu.

Otrzymasz jedno wejście: rozdzielony przecinkami ciąg poleceń.

Na przykład dla wejścia 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 wynikiem będzie:

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 rent

To wyzwanie łączy dziedziczenie (hierarchię Vehicle), interfejsy (Rentable), enumy (RentalStatus), własne wyjątki, polimorfizm (jednolite traktowanie różnych typów pojazdów) i kompozycję (RentalAgency zarządzająca pojazdami) w kompletny system wypożyczalni!

Spróbuj swoich sił

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: Utwórz instancję RentalAgency
        
        // TODO: Podziel dane wejściowe według przecinków, aby uzyskać poszczególne polecenia
        
        // TODO: Przetwórz każde polecenie:
        // ADD_CAR:licensePlate:brand:dailyRate:seats -> wypisz "Added: [brand] ([vehicleType])"
        // ADD_MOTORCYCLE:licensePlate:brand:dailyRate:engineCC -> wypisz "Added: [brand] ([vehicleType])"
        // RENT:licensePlate:days -> wypisz "Rented [licensePlate] for [days] days - Total: $[cost]" (2 miejsca po przecinku)
        //                           lub "Error: [exception message]", jeśli zostanie zgłoszony wyjątek
        // RETURN:licensePlate -> wypisz "Returned: [licensePlate]" lub "Return failed: [licensePlate]"
        // AVAILABLE -> wypisz "Available vehicles:", a następnie szczegóły każdego dostępnego pojazdu
        
        // TODO: Po przetworzeniu wszystkich poleceń wypisz "--- Fleet Summary ---"
        // a następnie szczegóły każdego pojazdu
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Java online