Composition & Inheritance

Why composition avoids rigid hierarchies, when inheritance genuinely earns its place, and polymorphism as a response to variation that is actually there.

Composition Over Inheritance

A hierarchy picks one axis of variation forever. A field can be swapped. That reversibility — not elegance — is the whole argument.

Q · Why does a three-level class hierarchy get expensive to change when the same behaviour held in fields does not?
When Inheritance Fits

Real substitutability, a closed and stable set of subtypes, and shared behaviour that is genuinely the same behaviour. Miss any one and you have coupled two types to save typing.

Q · Under what conditions is `extends` the right answer rather than the convenient one?
Polymorphism

One interface, several implementations, chosen because the behaviour genuinely differs. With one implementation it is not polymorphism — it is a redirect with a type on it.

Q · When does dispatching on a type buy something that a conditional does not, and when is it the same conditional hidden across six files?
Interface Versus Implementation

Depend on the narrowest thing that does the job. That is a different rule from "declare an interface for everything", and it more often means asking for less than for an abstraction.

Q · What should a function ask for — the concrete type, an interface, or just the two fields it actually reads?
Mixins, Traits and Embedding

Four languages, one problem: share behaviour without spending the inheritance slot. Each solution picks a different thing to give up, and knowing which tells you what the code will do under change.

Q · My language offers traits, mixins or embedding as a third option between inheritance and delegation. What does each one actually cost?