PL with abstract class
unknown
java
a month ago
7.3 kB
2
Indexable
Never
import java.util.ArrayList; import java.util.List; import java.util.Optional; public class ParkingLotSystem { // Enum for Vehicle Size public enum VehicleSize { SMALL, COMPACT, LARGE } // Abstract Class for Vehicle public abstract static class Vehicle { private String licensePlate; private VehicleSize size; public Vehicle(String licensePlate, VehicleSize size) { this.licensePlate = licensePlate; this.size = size; } public String getLicensePlate() { return licensePlate; } public VehicleSize getSize() { return size; } } // Interface for ParkingSpot public interface ParkingSpot { boolean isAvailable(); void parkVehicle(Vehicle vehicle); void removeVehicle(); Vehicle getVehicle(); int getSpotId(); } // Interface for ParkingLot public interface ParkingLot { Optional<ParkingSpot> findAvailableSpot(Vehicle vehicle); boolean parkVehicle(Vehicle vehicle); boolean leaveSpot(int spotId, int level); int availableSpots(); double calculateFee(int spotId, int level, long hoursParked); } // Interface for PaymentProcessor public interface PaymentProcessor { double processPayment(int spotId, long hoursParked); } // Implementing Vehicle Classes public static class Car extends Vehicle { public Car(String licensePlate) { super(licensePlate, VehicleSize.COMPACT); } } public static class Bike extends Vehicle { public Bike(String licensePlate) { super(licensePlate, VehicleSize.SMALL); } } public static class Truck extends Vehicle { public Truck(String licensePlate) { super(licensePlate, VehicleSize.LARGE); } } // Implementing ParkingSpot Class public static class SimpleParkingSpot implements ParkingSpot { private int spotId; private Vehicle currentVehicle; private VehicleSize spotSize; public SimpleParkingSpot(int spotId, VehicleSize spotSize) { this.spotId = spotId; this.spotSize = spotSize; } @Override public boolean isAvailable() { return currentVehicle == null; } @Override public void parkVehicle(Vehicle vehicle) { if (vehicle.getSize().ordinal() <= spotSize.ordinal()) { this.currentVehicle = vehicle; } } @Override public void removeVehicle() { this.currentVehicle = null; } @Override public Vehicle getVehicle() { return currentVehicle; } @Override public int getSpotId() { return spotId; } } // Implementing Level Class public static class Level { private int levelNumber; private List<ParkingSpot> spots; public Level(int levelNumber, int numberOfSpots, VehicleSize spotSize) { this.levelNumber = levelNumber; this.spots = new ArrayList<>(); for (int i = 1; i <= numberOfSpots; i++) { spots.add(new SimpleParkingSpot(i, spotSize)); } } public int getLevelNumber() { return levelNumber; } public Optional<ParkingSpot> findAvailableSpot(Vehicle vehicle) { return spots.stream() .filter(ParkingSpot::isAvailable) .filter(spot -> vehicle.getSize().ordinal() <= spot.getVehicle().getSize().ordinal()) .findFirst(); } public boolean parkVehicle(Vehicle vehicle) { Optional<ParkingSpot> availableSpot = findAvailableSpot(vehicle); if (availableSpot.isPresent()) { availableSpot.get().parkVehicle(vehicle); return true; } return false; } public boolean leaveSpot(int spotId) { for (ParkingSpot spot : spots) { if (spot.getSpotId() == spotId && !spot.isAvailable()) { spot.removeVehicle(); return true; } } return false; } public int availableSpots() { return (int) spots.stream().filter(ParkingSpot::isAvailable).count(); } } // Implementing MultiLevelParkingLot Class public static class MultiLevelParkingLot implements ParkingLot { private List<Level> levels; private PaymentProcessor paymentProcessor; public MultiLevelParkingLot(int numberOfLevels, int spotsPerLevel, VehicleSize spotSize, PaymentProcessor paymentProcessor) { this.levels = new ArrayList<>(); this.paymentProcessor = paymentProcessor; for (int i = 1; i <= numberOfLevels; i++) { levels.add(new Level(i, spotsPerLevel, spotSize)); } } @Override public Optional<ParkingSpot> findAvailableSpot(Vehicle vehicle) { for (Level level : levels) { Optional<ParkingSpot> availableSpot = level.findAvailableSpot(vehicle); if (availableSpot.isPresent()) { return availableSpot; } } return Optional.empty(); } @Override public boolean parkVehicle(Vehicle vehicle) { for (Level level : levels) { if (level.parkVehicle(vehicle)) { return true; } } return false; } @Override public boolean leaveSpot(int spotId, int level) { return levels.get(level - 1).leaveSpot(spotId); } @Override public int availableSpots() { return levels.stream().mapToInt(Level::availableSpots).sum(); } @Override public double calculateFee(int spotId, int level, long hoursParked) { return paymentProcessor.processPayment(spotId, hoursParked); } } // Implementing PaymentProcessor Class public static class FlatRatePaymentProcessor implements PaymentProcessor { private static final double RATE_PER_HOUR = 2.0; @Override public double processPayment(int spotId, long hoursParked) { return RATE_PER_HOUR * hoursParked; } } // Main Class for Testing public static void main(String[] args) { PaymentProcessor paymentProcessor = new FlatRatePaymentProcessor(); ParkingLot parkingLot = new MultiLevelParkingLot(3, 10, VehicleSize.COMPACT, paymentProcessor); Vehicle car = new Car("ABC123"); Vehicle bike = new Bike("XYZ456"); parkingLot.parkVehicle(car); parkingLot.parkVehicle(bike); System.out.println("Available spots: " + parkingLot.availableSpots()); parkingLot.leaveSpot(1, 1); System.out.println("Available spots after leaving: " + parkingLot.availableSpots()); double fee = parkingLot.calculateFee(1, 1, 3); System.out.println("Parking fee for 3 hours: $" + fee); } }
Leave a Comment