Bird
Raised Fist0

The 4 OOP Pillars with Interview Examples - Encapsulation, Abstraction, Inheritance, Polymorphism

LLDeasyInterview freq: high
Choose your preparation mode4 modes available
🏗️
The 4 OOP Pillars with Interview Examples - Encapsulation, Abstraction, Inheritance, Polymorphism
Master the core OOP principles with Java-specific interview examples and concurrency considerations.
easyOOP Foundations for InterviewsFreq: high
Prerequisites:OOP FundamentalsJava BasicsBasic Concurrency in Java
⚙️
Functional Requirements
  • Encapsulate class fields using private access modifiers and provide controlled access via getters/setters
  • Use abstract classes to define partial implementations with state and behavior
  • Implement inheritance to reuse and extend behavior
  • Demonstrate polymorphism via method overriding and interface realization
  • Show concurrency-safe access to mutable shared state using synchronized and volatile
  • Provide interview examples illustrating each OOP pillar with Java code
  • Explain why abstract classes are preferred over interfaces when state is needed
👤
Use Cases
  • Explain encapsulation with Java example
  • Demonstrate abstraction using abstract classes vs interfaces
  • Show inheritance hierarchy with method overriding
  • Implement polymorphism with dynamic method dispatch
  • Discuss concurrency issues related to shared state in OOP
  • Answer clarifying questions about Java-specific OOP mechanisms
🧑‍💻
Actors
  • Candidate
  • Interviewer
❓
Clarifying Questions to Ask
  • How many threads will access shared objects concurrently?
  • Are there any constraints on mutability or thread safety?
  • Should the design support extension without modifying existing classes (Open/Closed Principle)?
  • Is there a pricing or resource allocation strategy affecting object lifecycle?
  • What edge cases should be handled, e.g., null inputs or invalid states?
Out of Scope
✗ Advanced design patterns beyond basic OOP pillars
✗ Complex concurrency utilities like java.util.concurrent locks
✗ Performance optimization techniques
✗ Non-Java OOP languages or paradigms
🔢
Enumerations
enum AccessModifier
PRIVATE | PROTECTED | PUBLIC
Defines Java access levels explicitly to prevent misuse of field/method visibility and enforce encapsulation.
enum VehicleType
CAR | TRUCK | MOTORCYCLE
Example enum to demonstrate polymorphism and type-specific behavior in Java.
📦
EncapsulatedClass
2 fields
private int idprivate String name
Demonstrate encapsulation by hiding fields and exposing controlled access via getters and setters.
public synchronized int getId()Thread-safe getter for id field.
public synchronized void setName(String name)Thread-safe setter for name field with validation.
📦
AbstractShape
1 fields
protected String color
Provide abstraction with partial implementation and state; subclasses must implement area calculation.
public String getColor()Returns the color of the shape.
public void setColor(String color)Sets the color of the shape.
public abstract double calculateArea()Abstract method forcing subclasses to provide area calculation.
📦
Circle
1 fields
private double radius
Concrete subclass of AbstractShape implementing area calculation demonstrating inheritance and polymorphism.
public double calculateArea()Calculates area of the circle using radius.
public double getRadius()Returns the radius.
public void setRadius(double radius)Sets the radius.
📦
Vehicle
2 fields
private volatile String licensePlateprivate VehicleType type
Demonstrate polymorphism and encapsulation with thread-safe mutable state using volatile.
public String getLicensePlate()Returns the license plate.
public synchronized void setLicensePlate(String licensePlate)Sets license plate with synchronization to ensure visibility.
public VehicleType getType()Returns the vehicle type.
📦
PolymorphicPrinter
0 fields
Demonstrate polymorphism by printing different object types using overridden toString methods.
public void print(Object obj)Prints string representation of any object demonstrating dynamic dispatch.
🔗
Relationships
Circle──►AbstractShape[1..1]
inheritanceCircle depends on AbstractShape lifecycle
EncapsulatedClass──►AccessModifier[1..*]
associationAccessModifier independent, EncapsulatedClass references it
Vehicle◇──►VehicleType[1..1]
aggregationVehicleType can exist independently of Vehicle
PolymorphicPrinter──►Object[0..*]
associationPolymorphicPrinter uses Object references temporarily
🗄️
EncapsulatedClassTable
PK: id
Stores encapsulated class instances with id as primary key and name as clustering key.
🗄️
VehicleTable
PK: licensePlate
Stores vehicle data keyed by license plate and clustered by vehicle type.
🔌
GetEncapsulatedClass
Request
{
  "id": "int"
}
Response
{
  "id": "int",
  "name": "String"
}
Fetches encapsulated class instance by id.
🔌
UpdateVehicleLicensePlate
Request
{
  "oldLicensePlate": "String",
  "newLicensePlate": "String"
}
Response
{
  "success": "boolean"
}
Updates vehicle license plate ensuring thread-safe mutation.
🔌
PrintObject
Request
{
  "object": "Object"
}
Response
{
  "printedString": "String"
}
Prints string representation of any object demonstrating polymorphism.

Practice

(1/5)
1. In the Tic-Tac-Toe game server, the makeMove() method is not synchronized. Which exact sequence of events between Thread 1 and Thread 2 can cause two players to place their marks on the same cell (double-booking)?
medium
A. Thread 1 and Thread 2 both call makeMove() but on different board instances.
B. Thread 1 reads cell as empty, Thread 2 reads cell as occupied, both proceed to write.
C. Thread 1 locks the board, Thread 2 waits, then both mark different cells simultaneously.
D. Thread 1 checks cell is empty -> true, context switch before marking; Thread 2 checks cell is empty -> true, both mark cell concurrently.

Solution

  1. Step 1: Identify the race condition in makeMove()

    Without synchronization, the check-then-act sequence is vulnerable: Thread 1 checks if cell is empty and is preempted before marking.
  2. Step 2: Trace Thread 2's actions

    Thread 2 also checks the same cell, sees it empty, and proceeds to mark it. Both threads mark the same cell, causing double-booking.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Check-then-act gap without sync -> double-booking race [check]
Hint: Check empty -> context switch -> both mark same cell [check]
Common Mistakes:
2. In a parking lot system, if parkVehicle() is not synchronized, which exact sequence of Thread 1 and Thread 2 causes double-booking of the same spot?
medium
A. Thread 1 checks isAvailable() -> true, context switch; Thread 2 checks isAvailable() -> true; both park the vehicle in the same spot.
B. Thread 1 and Thread 2 both call parkVehicle() simultaneously and crash.
C. Thread 1 parks vehicle, then Thread 2 parks vehicle after spot is freed.
D. Thread 1 calls parkVehicle(), Thread 2 waits until Thread 1 finishes, then parks.

Solution

  1. Step 1: Identify the check-then-act race condition

    Without synchronization, Thread 1 reads spot as available, then context switches before marking it occupied.
  2. Step 2: Trace Thread 2's actions

    Thread 2 also reads spot as available and proceeds to park, causing double-booking.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Unsynchronized check-then-act -> both threads see available -> double-booking [check]
Hint: Check-then-act gap without sync -> double-booking race [check]
Common Mistakes:
3. You need to add support for ElectricCar that requires ChargingSpot compatibility in the current parking system. What is the minimum change to the design to support this without modifying existing classes?
hard
A. Modify Vehicle class to add a boolean needsCharging and update parking logic to check this flag.
B. Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType, create ElectricCar subclass, and update SpotCompatibility.COMPATIBILITY_MAP accordingly.
C. Create a new ElectricParkingLot subclass that handles electric cars and charging spots separately.
D. Add a ChargingSpot field to Vehicle and modify all parking methods to handle it.

Solution

  1. Step 1: Identify extensibility requirements

    ElectricCar and ChargingSpot are new types requiring compatibility mapping without changing existing classes.
  2. Step 2: Apply minimal invasive change

    Adding new enum values and subclass plus updating compatibility map extends functionality without modifying existing class code, preserving OCP.
  3. Step 3: Avoid violating OCP

    Options B, C, and D modify existing classes or create parallel hierarchies, increasing complexity and violating OCP.
  4. Final Answer:

    Option B -> Option B
  5. Quick Check:

    Extend enums and map, subclass ElectricCar -> minimal change [check]
Hint: Extend enums and map, subclass new type -> minimal change [check]
Common Mistakes:
4. ElectricCar vehicles require ChargingSpots in the parking module. What is the minimum change to the current Java design to support this without modifying existing classes?
hard
A. Create a new ElectricCar class and a ChargingSpot class, then modify ParkingLot to handle both types explicitly.
B. Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar subclass, and update SpotCompatibility.COMPATIBILITY_MAP.
C. Modify Vehicle class to include a boolean isElectric field and add logic in existing parking methods.
D. Add a new interface Chargeable and make ElectricCar implement it, modifying existing Vehicle and Spot classes.

Solution

  1. Step 1: Identify extensibility without modifying existing classes

    Minimal change means no modification to existing classes; adding new enums or modifying compatibility map violates this.
  2. Step 2: Use composition or flags to extend behavior

    Adding an isElectric boolean field to Vehicle and handling charging logic externally avoids class explosion and preserves OCP.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Flag in Vehicle + external logic -> minimal change, no class modification [check]
Hint: Add flag + external logic -> minimal change, no class edits [check]
Common Mistakes:
5. To add support for ElectricCar objects requiring ChargingSpots in the existing LRU Cache design (which models Vehicle and Spot types), what is the minimum change that respects extensibility and avoids modifying existing classes?
hard
A. Modify Vehicle base class to include a boolean isElectric field and add logic in Spot class to check this field.
B. Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar subclass, and update SpotCompatibility map; no existing classes modified.
C. Create a new ElectricCar class and a new ChargingSpot class, then modify the Cache class to handle these new types explicitly.
D. Add a new method in Vehicle interface for charging compatibility and implement it in ElectricCar; modify Spot class accordingly.

Solution

  1. Step 1: Identify extensibility requirements

    We want to add ElectricCar and ChargingSpot without modifying existing classes to respect OCP.
  2. Step 2: Evaluate options

    Modify Vehicle base class to include a boolean isElectric field and add logic in Spot class to check this field. modifies existing Vehicle class, violating OCP. Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar subclass, and update SpotCompatibility map; no existing classes modified. adds enum values and compatibility map without changing existing classes, preserving extensibility.
  3. Step 3: Confirm minimal change

    Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar subclass, and update SpotCompatibility map; no existing classes modified. adds new enum constants and new subclass, updating compatibility map externally, no existing class code changed.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    New enums and subclass added, existing classes untouched [check]
Hint: Add enums and subclass, avoid modifying existing classes [check]
Common Mistakes:
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard