> using a function pointer has unnecessary overhead
This is true, it's inefficient. But for a lot of application, also irrelevant at performance level, and would provide a good abstraction.
> using a function pointer has unnecessary overhead
This is true, it's inefficient. But for a lot of application, also irrelevant at performance level, and would provide a good abstraction.
It got a bad reputation because it was abused. Bad practice is using inheritance when a tuple or a map would suffice.
Inheritance (from implementation, I've nothing against implementation of interfaces or inheritance from abstract base classes) has a ton of problems, more importantly the fact that it makes the code more difficult to understand and to evolve.
Composition on the other hand is something more natural, even if we think about real life: you don't usually take an object and "extend" it, you take multiple object and use them together to build something!
I don't know why we need to be so judgmental about it.
I think inheritance is especially good if you have an interface (in the OO sense, like some languages use an "interface" keyword for), but you have some common or default methods, which a specific implementation may or may not override, or maybe there is some boiler plate or tedium where the most common implementation might belong in a base class. I think this is handy for something like a device driver.
> has a ton of problems
this may be a good reference with examples (and some good dose of nuance) on the subject:https://blog.gougousis.net/oop-inheritance-what-when-and-why...
Traits are like interfaces in OOP languages (simplified), the equivalent of a class would be a struct + all the impls of that struct. And that thing cannot be extends, a struct is fixed when defined and nobody can extend it, you can use composition that is the correct to me way to go.
Traits describe the methods implemented, and you can override with specific implementations or inherit the default, from a level up.
Right... There is an animal in a dog.