4 ms·
It does, because it is no longer a matter of substitutability. You are not intrinsically taking an X and modifying it to become a Y while also being an X. You a
by jerf 2y ago
It does, because it is no longer a matter of substitutability. You are not intrinsically taking an X and modifying it to become a Y while also being an X. You are now just providing an X, and another X, and another X, and another X over there. You need to maintain the constraints of the one interface you are satisfying, but you are not also maintaining the constraints of the superclass, and all of its superclasses. You only have the interface to worry about, only the one dimension, not two (or more, depending on how you count in multiple inheritance languages).
You also can do things like take a subset of the interface and have things that implement just that. You can't do that to a class hierarchy; once a method is put in the hierarchy, it must be implemented by all children. (Note that if you're jumping up to say "But I can just implement an interface in Java or whatever if I want to do that", you're agreeing with me, not disagreeing. That's not a legal move in inheritance, though. Languages have been very, very slowly but very surely moving away from pure inheritance for a long time now.)
Having interfaces separated from reusability means you don't have to worry about all these things at once, just the interface.
- pvg 2y agoI think trying to overformalize this by bringing in LSP might make it harder to understand and easier to nitpick. Another way to look at the same thing is that subclassing/implementation inheritance is an extremely stringent but poorly enforced contract (yeah, also a kind of formalism) that's, in your typical OO language, far too easy break without noticing.
- jerf 2y agoIronically, the fact that LSP is complicated and to a first approximation nobody understands it is a major part of my point. (Or, if you prefer, LSP itself isn't that complicated conceptually, but if you try to manifest it in reality it turns out to be very complicated in practice. Code makes a lot more guarantees than we think it does. See also https://hyrumslaw.com/ https://hyrumslaw.com/ , which a very different view on the same phenomenon.)
- tome 2y agoI agree. I think the LSP makes it essentially impossible to subclass a concrete superclass, because the subclass must retain all the observable behaviour of the superclass. If it does so then what's the point? On the other hand, implementing an interface is fine. Different implementations of the interface can just uphold the interface invariants without needing any relationship to each other.