Multiple inheritance and interfaces
Essence
Multiple inheritance is when a class inherits implementation from several parents (C++, Python). The main problem is the diamond problem: D inherits B and C, both inherit A and override the same method; which version does D get, and how many copies of A's state does it hold? Because of this ambiguity and fragility, most languages forbid multiple class inheritance.
How languages solve it
- Java and C#: single class inheritance plus several interfaces; since Java 8 / C# 8 interfaces may carry default methods and conflicts must be resolved explicitly.
- Swift and Objective-C: single class inheritance plus any number of protocols. In Swift protocols can carry behaviour through
extensions, giving "multiple inheritance of behaviour" without inheriting state. - Mixins/traits (Ruby, Scala, Rust) are named bundles of methods mixed into a type; Swift protocol extensions play the same role.
The diamond in Swift and how it is resolved
protocol Flying { func move() -> String }
protocol Swimming { func move() -> String }
extension Flying { func move() -> String { "fly" } }
extension Swimming { func move() -> String { "swim" } }
struct Duck: Flying, Swimming {
// Without this the call `Duck().move()` is ambiguous: two defaults.
func move() -> String { "fly or swim" }
}
print(Duck().move()) // fly or swim
print((Duck() as any Flying).move()) // fly or swim: requirement overridden
If Duck does not implement move() itself, the compiler reports an ambiguity error: the conflict is resolved explicitly rather than by ordering rules as in C++ or Python (MRO).
Why protocols are safer
- A protocol stores no state (only property requirements), so there are no duplicated fields.
- A clash of default implementations is a compile error, not a silent pick of one variant.
- Protocols are adopted by
struct/enum/actor, which cannot inherit at all.
What the interviewer looks for
- The dispatch trap: a method declared only in an
extension(not a protocol requirement) is dispatched statically by the variable's type. - Understanding that "stored properties are forbidden in extensions" has a consequence: a protocol can bring only a contract and behaviour, never state.