0

The discussion comes up here:

Changing visibility of method in inherited class

question is: is really "BTNode extends GraphNode" design a violation of Liskov's Substitution Princeple? As an "similar" example it was shown that case: Is deriving square from rectangle a violation of Liskov's Substitution Principle?

but I cannot really see why that is similar. I am very new to design, could someone explain me why (if) that's the case?

Malvinka
  • 1,185
  • 1
  • 15
  • 36

1 Answers1

2

In Is deriving square from rectangle a violation of Liskov's Substitution Principle?, it basically says that Square cannot inherit from Rectangle because there are things that you can do with Rectangles but not with Squares - setting its width to a different number from its height.

You can't inherit BTNode from GraphNode because according to the original post you linked, GraphNode has a method called addChild. BTNode on the other hand, can only have two children. Inheriting from GraphNode will also inherit the addChild method. This allows you to add multiple children to BTNode, which a BTNode cannot handle.

Therefore, BTNode cannot inherit from GraphNode because there are things that you can do with GraphNodes but not with BTNodes - adding multiple children.

For completeness, here is the Liskov's Substitution principle from Wikipedia

Subtype Requirement: Let ϕ(x) be a property provable about objects x of type T. Then ϕ ( y ) should be true for objects y of type S where S is a subtype of T.

In simple terms,

If you can do action X on type T, you should also be able to do action X on any subclasses of T.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • Does restricting number of children wouldn't solve that problem? It could be done in one of two ways: by adding numberOfChildrenRestricion flag to GraphNode (that shows how many children that particular graphNode may have) or by overriding addChild in BTNode so that it won't allow to add more then two children (and, for example, throw an exception)? – Malvinka Aug 26 '17 at 16:39
  • If I decide not to derive BTNode from GraphNode it would mean rewriting basically the whole code (but addChild method) from one class to the other - that does not seem reasonable as well... – Malvinka Aug 26 '17 at 16:41
  • 1
    @Malvinka No, `BTNode` specifically has a child on the left and one on the right. It's ambiguous which side `addChild` will add a child to. – Sweeper Aug 26 '17 at 16:41
  • 1
    @Malvinka Have you ever thought of going wild and adjust your `addChild`, to accept 2 parameters - `Node` and `Position`? Don't get caught in this rigid theory. Just think what your objects have in common and good design will come to you. – Janez Kuhar Aug 26 '17 at 16:42
  • You can always inherit them both from a `Node` class. @Malvinka – Sweeper Aug 26 '17 at 16:42