|
|
|
|
|
by legulere
3276 days ago
|
|
Aggregation and composition are almost the same, are not distinguished in e.g. Java and exist in pretty much every rogramming language regardless if they are object-oriented.
Inheritance is presented everywhere as the go-to method for structuring everything in languages supporting inheritance. The whole java class library consists of huge class hierarchies. Every non-trivial java code base I have seen is heavily infested with inheritance. Inheritance together with other forms of polymorphism are the biggest differentiator to structural programming in e.g. C. Inheritance is everything else but safe: you have to check if you broke the behavior of all methods and public fields you are inheriting. How often do you go through all classes you are inheriting from?
Sometimes you cannot even fix this with overriding methods:
You can easily construct a cut off ellipsoid from a regular ellipsoid, but then it stops being a quadric surface invalidating your nice class hierarchy. And you cannot change the class hierarchy because half of your codebase depends on it. Patterns are like neat useful tricks. Like how to open a bottle with a hammer. Pretty nice to open your beer at the end of the day in a workshop. If you work in a bar and you constantly have to use tricks to use your hammer for your work you should probably rethink if a hammer is the right main tool for you. |
|
That conclusion holds if your primary experience is Java: the Java class library is widely believed to have abused inheritance.
However other languages have avoided that trap. Apple's Cocoa frameworks in ObjC do use inheritance but also delegation, notifications, etc. Also Swift supports inheritance, but here we see Lattner describing inheritance as a "tool in our toolbox," not as the "go-to method for structuring everything."
> Inheritance is everything else but safe: you have to check if you broke the behavior of all methods and public fields you are inheriting.
Designing a class interface intended to be inherited is like any other API design exercise. Your API commits to invariants, and it's the client programmer's responsibility to follow them; if they do the class should not be broken.
If you find yourself checking "all methods and public fields," either the API is bad or you've misunderstood it.
Again, it's just one API design tool. Sometimes the alternative to inheritance is just an ad-hoc, bug-ridden re-implementation of inheritance.