6 ms·
It seems nuts to me that anyone would expect the Queen class to extend Bishop just because they happen to move diagonally. A Queen "IS NOT A" Bishop. If anythi
by hota_mazi 9y ago
It seems nuts to me that anyone would expect the Queen class to extend Bishop just because they happen to move diagonally. A Queen "IS NOT A" Bishop.
If anything, specify traits that define the movement of the pieces and have each piece extend that trait (with the Queen extending both CAN_MOVE_DIAGONALLY and CAN_MOVE_LATERALLY).
- qznc 9y agoYes. A similar way to argue is Liskov's substitution principle [0]. It is easy to come up with properties that always hold for bishops, but not for queens. For example, bishops never move from black to white fields or vice versa. [0] https://en.wikipedia.org/wiki/Liskov_substitution_principle https://en.wikipedia.org/wiki/Liskov_substitution_principle
- jgalt212 9y agocomposition over inheritance https://en.wikipedia.org/wiki/Composition_over_inheritance https://en.wikipedia.org/wiki/Composition_over_inheritance
- hota_mazi 9y agoNo, my observation has nothing to do with composition vs/ inheritance. It's about defining what a class IS vs/ what a class HAS.
- mikekchar 9y agoIt's hard to ask this question without sounding snarky, but I hope you will understand that I'm seriously curious to hear what you think. > No, my observation has nothing to do with composition vs/ inheritance. > It's about defining what a class IS vs/ what a class HAS. What do you feel is the difference between these two sentences? In other words, why is inheritance vs composition not the same as what a class is vs what a class has?
- hota_mazi 9y agoThese concepts are orthogonal. I can use composition and inheritance to define an IS_A relationship and I can use them to define a HAS_A relationship. For example, in Kotlin: class A : B // IS_A via inheritance class A(b: B) { // HAS_A via composition class A(b: B) : B by b // IS_A via composition
- eiffel31 9y ago> class A(b: B) : B by b // IS_A via composition I couldn't find the "B by b" syntax from the Kotlin docs, can you tell me that this does ?
- imtringued 9y agoPeople are overthinking this. In practice inheritance is a very special case of composition that is only advantageous in a very narrow set of usecases. Basically almost never. In fact the number of usecases is so low that I would prefer that modern languages just omit it entirely because the added value is incredibly tiny compared to the cost of confused developers. The primary difference between an interface and inheritance is that with inheritance you do not have to implement every method and can use the default implementation of the base class. Example: class Piece { int x int y boolean validMove(int newX, int newY) { return false; } } class Queen extends Piece { boolean validMove(int newX, int newY) //we use the default implementation } Is equivalent to this interface IPiece { boolean validMove(int newX, int newY); } class Piece() implements IPiece { int x int y boolean validMove(int newX, int newY) { return false; } } class Queen implements IPiece { Piece piece; boolean validMove(int newX, int newY) { //we use the default implementation return piece.validMove(newX, newY); } } Inheritance doesn't actually offer any code reuse. All it does is choose the default implementation of the parent class. If you have dozens of polymorphic functions in a class and only want to change 3 it might be convenient. I would question why you need so much polymorphism to warrant a special language feature. C and Rust developers are fine without it. Functional programmers are fine without it. But for some reason in OOP you need it everywhere and are actually worse off because it's overused. Modern language designers, please do not implement inheritance of classes in your new languages!
- wbkang 9y agoIt is reasonable for implementation re-use (subclassing) but it flunks the subtyping aspect.