4 ms·
The first step in separating polymorphism and inheritance is understanding that there are several forms of polymorphism. The one that gets lumped in with inheri
by pdpi 3y ago
The first step in separating polymorphism and inheritance is understanding that there are several forms of polymorphism. The one that gets lumped in with inheritance is subtype polymorphism, but there's at least two other sorts (not an expert, there may be more?): parametric polymorphism ("generics") and ad-hoc polymorphism (e.g. rust traits, haskell typeclasses). All of these achieve one form of code sharing, which is that, in one way or another, code that only depends on your external interface can be reused with any implementation of that external interface.
The other place you want code sharing is the implementation of that external interface. Inheritance is one well-known way to do this, but composition/delegation is another strategy to achieve the same thing. Golang's embedded structs are a pretty streamlined (but fairly limited) way of achieving this, and e.g. Kotlin has explicit delegation: `class Derived(b: Base) : Base by b`. Languages like e.g. Java (where classes are open by default) push you towards inheritance, while languages like Kotlin (where classes are final by default, and where you have explicit support for delegation) push you towards composition.
A whole lot of confusion comes from most mainstream OOP languages conflating inheritance and subtype polymorphism.
- ulrikrasmussen 3y agoRow polymorphism is another sort which is only concerned with record types and allows functions to operate on a section of a record without losing type information.