Software/Inheritance/Multiple/vs/Single
Summary
- Under single inheritance a class has one parent, so every inherited member traces up one chain. Under multiple inheritance a class may name several parents, which fits an object that really is several kinds of thing at once. The cost of multiple inheritance is conflict: two parents can define the same member, or reach a shared ancestor by two paths, and the language needs a rule for which definition wins.
- Languages draw the line in different places. C++ and Python allow several parent classes. Java allows one parent class and any number of interfaces, and since Java 8 an interface can carry default method bodies, so a class that inherits two conflicting defaults must override the method. Ruby modules and Scala traits are mixins: single inheritance for the main chain, with extra behavior mixed in.
The Trade-Off
- Choosing multiple inheritance means a class may name several parents and inherit members from each.
- Gains — an object that is several kinds of thing at once inherits from each kind directly, with no copied code and no wrapper objects.
- Costs — two parents can define the same member, and a shared ancestor can be reached by two paths, the diamond problem. Reading the class means knowing the resolution order to see where a member comes from.
- Too far — a tangled graph of parents where reordering the list of bases silently changes behavior.
- Choosing single inheritance means each class has one parent; other reuse goes through interfaces, mixins, or Software/Composition.
- Gains — one chain to read, no diamond, and member lookup that anyone can follow by walking up the chain.
- Costs — an object that is two kinds of thing must pick one parent and reach the other through an interface, a collaborator, or copied code.
- Too far — unrelated capabilities forced into one chain, producing base classes that collect everything any descendant might need.
How the balance is struck
- Keep one main lineage and let extra parents add capabilities that do not overlap with it. Mixins and traits follow this pattern.
- When parents can overlap, state the resolution order and keep it predictable. Python computes a method resolution order with the C3 linearization and looks up each member in that order, so among a class's direct parents the one listed first wins.
- When the extra parent is something the class uses rather than something it is, Software/Composition fits better; Software/Composition/vs/Inheritance weighs that choice.
In this garden
- Logseq/Entity lets one page declare several entities, primary first, and the page satisfies the shape rules of each. That is multiple inheritance of page-shape rules, with the listed order as the resolution order. Logseq/Entity/Hierarchy/Discussion holds dated analyses of which entities one page may carry together and where the rules for a combination of entities go.
Sources