I like rust a lot, but coming from C++ and python there are times inheritance saves so much time enabling quickly creating small variations in classes. In rust you have to duplicate all the base logic, or abstract it to another common type to use composition. Which is fine but it’s painful at times knowing that time sink lies ahead. I understand everyone hates OO now but I still miss it at times when it would save me a lot of effort.
If you can use C++20, I'd encourage you to look into using concepts. Since I've started using them, it feels like a much more natural choice than class hierarchies when one needs to enforce type constraints on interfaces.
Instead of making a parent class that has a few key methods you need (e.g. send, recv) with the signatures (e.g. takes a pointer, returns a number), one can encode the use of those functions in a concept (e.g. a "socket" concept). This decouples the implementation from the use in the method, with the one big advantage being that it is easily testable -> no more need to carefully craft type hierarchies to carefully be able to substitute some mock object when you can just directly call it!
OO hierarchies certainly still have their place (even though so many conference talks seem to be about getting rid of them), but I'm glad I can relegate them to a dark corner of my toolbox until I absolutely need them.
In fact, come to think of it C++ concepts are basically Rust traits!
Yea for sure, it’s a lot like swift being protocol oriented too. It’s a major paradigm shift I have to enforce in my head manually still at this point tho
That it works for any type implementing the trait, via vtables. Otherwise, it’s a method specific to the particular type implementing the trait (a concrete implementation but distinct to the specific impl).
To be fair, a trait gets you 98% there. It can have default implementations for most functions, you just overwrite the ones you want to change.
You'll still need to declare the underlying struct though, so a bit of extra code
In my programming career, I had several situations where a base class made a lot of sense, with a dozen derived classes only implementing specific functionality. They were mostly algorithm-related.
I often find the opposite to be true. Where I have to spend a lot of time clearly defining a hierarchical structure, which after implementation needs to restructured. Or fighting against an already defined hierarchy, usually unchangeable and made by someone else.
Can you imagine a non-inheritance solution to this problem? If you used this way of solving things your whole life then I understand that changing paradigms is a challenge.
Since there was no answer, and no concrete example where inheritance was needed, I'll just provide one possible solution: you can store a function pointer that implements the desired varying functionality as a part of the struct whose implementation you want to slightly change. That function can accept self as the first argument like any method.
Performance-wise this is the same as a vtable generated by c++ and doesn't require creating more entities.