When would you choose composition over inheritance?
LanguagesMid-level
In shortUsually. Inheritance couples a subclass to its parent's internals and multiplies classes when behavior varies along several dimensions; composition gives an object the parts it needs, each replaceable on its own. Keep inheritance for stable is-a relationships.
Model answer
Inheritance gives you code reuse and a subtype in one step, and that’s its problem: the subclass depends on how the parent is implemented. Change the parent (which methods call which) and subclasses can break without being touched. It also scales badly: notifications by channel × urgency × timing become ScheduledUrgentPushNotification and a dozen siblings.
Composition gives an object the parts it needs: a notification has a channel, an urgency and a timing. Each part varies on its own, is replaceable in tests, and adding a channel is one new type.
Inheritance is still right for a genuine, stable is-a relationship, or when a framework requires it (subclassing a view or an Activity). Even then, mark classes final (Kotlin’s default) unless they’re designed to be extended, and avoid calling overridable methods from constructors.
What they're looking for
The coupling cost of inheritance (fragile base class), the combinatorial explosion example, delegation as the alternative, and a case where inheritance is still right.
Common mistakes
- Saying inheritance is always bad.
- Not giving a concrete example.
- Ignoring language defaults (Kotlin final classes, Swift final and value types).
More languages questions
- How is memory managed in Swift compared to Kotlin or Java?Mid-level
- What is the difference between a value type and a reference type?Junior
- What is the difference between checked and unchecked exceptions, and how do Kotlin and Swift handle this?Mid-level
- What are type erasure and variance in generics, and how do Swift, Kotlin and Java differ?Senior