OOP FundamentalsInheritance & CompositionMedium⏱️ ~3 min

Application: Parking Lot Payment System

Scenario: Parking Lot Payment Processing

Design a parking lot system where vehicles park in spots and payment is calculated based on vehicle type and duration. We need to handle different vehicle types and multiple payment methods.

Design Decision: When to Use Each

Use Inheritance for Vehicle Types: Different vehicles (Car, Motorcycle, Truck) share common attributes (license plate, entry time) but have type-specific pricing rules. They are legitimately different types of the same concept.

Use Composition for Payment Processing: A ParkingTicket should not "be a" payment method. Instead, it should "have a" payment strategy that can be swapped. This allows runtime flexibility to handle cash, card, or digital wallet payments.

Inheritance: Vehicle Hierarchy
Vehicle
- licenseNumber: String
- entryTime: DateTime
+ getFeeMultiplier(): double
+ getSpotSize(): SpotSize
Car
getFeeMultiplier(): 1.0
getSpotSize(): COMPACT
Motorcycle
getFeeMultiplier(): 0.5
getSpotSize(): SMALL
Truck
getFeeMultiplier(): 2.0
getSpotSize(): LARGE
Composition: Ticket with Payment Strategy
ParkingTicket
- vehicle: Vehicle
- paymentStrategy: PaymentStrategy
- exitTime: DateTime
+ calculateFee(): Money
+ processPayment(): Receipt
«interface»
PaymentStrategy
+ pay(amount): Receipt
CashPayment
pay(amount)
calculateChange()
CardPayment
pay(amount)
authorizeCard()
WalletPayment
pay(amount)
verifyBalance()
Why This Design Works

First, inheritance for vehicles is appropriate because a Car truly "is a" Vehicle, and all vehicle types share core parking behavior while overriding type-specific details like fee calculation.

Second, composition for payment allows the ParkingTicket to switch payment methods at runtime without changing its type. A ticket does not "become" a cash payment; it uses a cash payment strategy.

Third, if we incorrectly used inheritance for payments (CashTicket, CardTicket), we would need separate ticket classes for each payment type, violating the Single Responsibility Principle (SRP) and creating a combinatorial explosion of classes.

Interview Tip: When asked to design a parking lot, explicitly state why you are choosing inheritance for vehicles and composition for payment. Mention flexibility and the Open-Closed Principle (OCP).
💡 Key Takeaways
Use inheritance when subclasses are genuine specializations of the parent
Use composition when you need to swap behavior at runtime
Vehicle hierarchy uses inheritance because Car is a Vehicle
Payment uses composition because Ticket has a payment strategy
Composition with interfaces enables the Strategy pattern
📌 Examples
1ParkingTicket composes Vehicle and PaymentStrategy
2Vehicle inheritance hierarchy for type-specific pricing
3Payment strategy pattern for flexible payment processing
4Spot allocation based on Vehicle.getSpotSize()
← Back to Inheritance & Composition Overview
Application: Parking Lot Payment System | Inheritance & Composition - System Overflow