OOP FundamentalsInheritance & CompositionHard⏱️ ~4 min

Interview Deep Dive: Common Questions and Variations

Question 1: Design a Library Management System

The Setup: You need to model books, members, and borrowing. How do you handle different member types (Student, Faculty, Guest) and different book types (ReferenceBook, RegularBook, Magazine)?

Strong Answer Approach

First, use inheritance for Member types. Student, Faculty, and Guest are genuinely different member categories with shared attributes (memberId, name) but different borrowing limits and privileges. This passes the is-a test.

Second, use inheritance for Book types. ReferenceBook and RegularBook share core book attributes (ISBN, title, author) but have different borrowing rules (reference books cannot be borrowed).

Third, compose a BorrowingPolicy into Member. Instead of hardcoding limits, inject a policy that can be changed. A Faculty member might upgrade their policy without changing their member type.

Library System Design
Member
- memberId: String
- policy: BorrowingPolicy
+ borrowBook(book): boolean
«interface»
BorrowingPolicy
+ canBorrow(): boolean
+ getMaxBooks(): int
Student
Faculty
Guest
Question 2: The Bird-Penguin Problem

The Setup: You have a Bird class with a fly() method. How do you handle Penguin, which cannot fly?

Wrong Approach (LSP Violation)
class Penguin extends Bird {
  fly() { throw new UnsupportedException() }
}
This breaks Liskov Substitution Principle. Code expecting a Bird will fail with Penguin.
Correct Approach (Interface Segregation)

First, separate Flyable interface from Bird. Not all birds fly.

Second, birds that fly implement Flyable and compose FlyingBehavior.

Third, Penguin extends Bird but does not implement Flyable. It composes SwimmingBehavior instead.

Question 3: Vending Machine Design

The Setup: Design a vending machine that dispenses products, accepts payment, and maintains inventory. How do you model products and payment methods?

Optimal Design

Product Hierarchy (Inheritance): Beverage, Snack, and Sandwich all extend Product. They share price and inventory management but have different dispensing mechanisms.

Payment Strategy (Composition): VendingMachine composes PaymentProcessor, which uses a PaymentMethod interface. This allows cash, card, and mobile payments without changing the machine's core logic.

State Pattern (Composition): VendingMachine composes VendingMachineState (Idle, AcceptingPayment, Dispensing). State changes at runtime without inheritance.

Interview Tip: When designing systems, first identify entities that form natural hierarchies (use inheritance), then identify behaviors that need runtime flexibility (use composition with Strategy or State patterns).
Common Follow-up: Multiple Inheritance

Question: What if an object needs behaviors from multiple sources? For example, an Amphibian that swims and walks.

Answer

First, most modern languages avoid multiple inheritance due to the Diamond Problem (ambiguous method resolution).

Second, use interfaces plus composition. Amphibian implements Swimmable and Walkable, and composes SwimmingBehavior and WalkingBehavior.

Third, this approach avoids inheritance ambiguity while providing multiple capabilities. Each behavior is independently testable and replaceable.

Machine Coding Considerations
Time Management: In a 90-minute machine coding round, start with inheritance for core domain entities. Add composition for flexibility only after basic functionality works. Do not over-engineer early.

First, define base classes and hierarchies. This establishes the domain model quickly.

Second, implement core methods with hardcoded logic. Get the parking lot working with basic car parking first.

Third, refactor to composition for payment or pricing strategies if time permits. Mention to the interviewer that you are aware of Strategy pattern but prioritizing working code.

Fourth, if asked to extend the system (add a new vehicle type or payment method), this is when you showcase composition. Show how adding ElectricCar extends Vehicle (inheritance) and adding CryptocurrencyPayment implements PaymentStrategy (composition) without modifying existing code (Open-Closed Principle).

Red Flags Interviewers Watch For

First, blindly applying "composition over inheritance" without justification. If you refuse to use inheritance even for clear hierarchies like Shape-Circle, you signal dogmatism over understanding.

Second, creating inheritance hierarchies based on implementation sharing rather than conceptual relationships. If you make CircleWithLogging extend Circle just to add logging, you misunderstand inheritance. Use a decorator or aspect instead.

Third, violating LSP by making subclasses weaker than parents. If Square extends Rectangle but breaks because setting width independently does not work, you have misused inheritance. In this case, both should implement a Shape interface.

💡 Key Takeaways
Member-Student-Faculty uses inheritance for stable type hierarchy
BorrowingPolicy uses composition for flexible borrowing rules
Bird-Penguin problem demonstrates LSP violation and fix with interfaces
VendingMachine uses composition for PaymentMethod and State
Multiple capabilities (swim, walk) need interface composition, not multiple inheritance
📌 Examples
1Library system with Member hierarchy and BorrowingPolicy composition
2Bird with Flyable interface to handle Penguin correctly
3VendingMachine with Product hierarchy and PaymentStrategy composition
4Amphibian implementing multiple interfaces with composed behaviors
← Back to Inheritance & Composition Overview
Interview Deep Dive: Common Questions and Variations | Inheritance & Composition - System Overflow