Take Rust as an example, composition implemented in modern languages is really a mix of both paradigms.
In the Advantages of Inheritance section, we can emulate the inheritance way by adding a IndefinitelyDoStuff type class (or interface). The type’s capability is extent by type class hierarchy and code duplication is mitigated by default implementation.
Inheritance provides a safer experience due to compile time guarantees […] the code simply doesn’t compile until you’ve updated all child classes
Similarly, adding that to the type class declaration will enforce implementation for each instance to be added at compile time.
Take Rust as an example, composition implemented in modern languages is really a mix of both paradigms.
In the Advantages of Inheritance section, we can emulate the inheritance way by adding a
IndefinitelyDoStuff
type class (or interface). The type’s capability is extent by type class hierarchy and code duplication is mitigated by default implementation.Similarly, adding that to the type class declaration will enforce implementation for each instance to be added at compile time.