Why prefer composition over inheritance?
TL;DR: Inheritance creates tight coupling and fragile base classes — a change in the parent can break all subclasses. Composition adds behavior through contained objects and interface delegation, keeping changes isolated and classes focused.
Full Answer
The Gang of Four Design Patterns book famously states 'favor object composition over class inheritance'. Inheritance is an 'is-a' relationship; composition is a 'has-a' relationship.
The Fragile Base Class Problem
When MyBloc extends BaseBloc, any change to BaseBloc can break MyBloc. With 20 subclasses, BaseBloc becomes untouchable.
Composition Solution
Instead of extending, hold a reference to a LoggingService. Swap the implementation without touching MyBloc.
Code Examples
// Composition: UserService testable without any base class // Change Dio → GraphQLClient: only update constructor call site
Common Mistakes
- ✗Using inheritance just to reuse code — that's what mixins and composition are for
- ✗Deep inheritance hierarchies (A → B → C → D) — changes at A ripple down unpredictably
Interview Tip
Use the Flutter widget tree as an example: Widget composition (wrapping in Container, Padding, DecoratedBox) vs inheriting from a base widget. Flutter's own design is composition-first.