PL with abstract class
unknown
java
a year ago
7.3 kB
10
Indexable
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);
}
}
Editor is loading...
Leave a Comment