1

After reading this post I think I mostly understand LSP and most of the examples, but I can’t say I’m 100% certain from my experience of many examples of inheritance, as it seems that many examples do violate LSP and it seems difficult not to when overriding behaviour.

For instance, consider the following simple demonstration of inheritance, taken from Head First Object Oriented Analysis & Design. Aren't they violating LSP with the Jet child class?

public class Airplane {
  private int speed;

  public void setSpeed(int speed) {
    this.speed = speed;
  }
  public int getSpeed() {
    return speed;
  }
}

public class Jet extends Airplane {
  private static final int MULTIPLIER=2;

  /**
   * The subclass can change behaviour of its superclass, as well as call the
   * superclass's methods. This is called overriding the superclass's behaviour
   */
  public void set setSpeed(int speed) {
    super.setSpeed(speed * MULTIPLIER);
  }

  public void accelerate() {
    super.setSpeed(getSpeed() * 2);
  }
}

A client using a reference to an instance of base class Airplane might be surprised, after setting the speed, to find it is twice as fast as expected after being passed an instance of a Jet object. Isn't Jet changing the post-conditions for the setSpeed() method and thus violating LSP?

E.g.

void takeAirplane(Airplane airplane) { 
    airplane.setSpeed(10);
    assert airplane.getSpeed()==10;
}

This will clearly fail if takeAirplane is passed a reference to a Jet object. It seems to me that it will be difficult not to violate LSP when “overriding a superclass’s behaviour”, yet this is one of the main/desirable features of inheritance!

Can someone explain or help clarify this? Am I missing something?

Andy Birchall
  • 311
  • 1
  • 3
  • 12

1 Answers1

1

According to Wikipedia

[The Liskov substitution principle] states that, in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may substitute objects of type T) without altering any of the desirable properties of that program (correctness, task performed, etc.).

In the case of the Jet, it's speed being twice as fast is a violation of the LSP - it fails the postcondition that setSpeed(getSpeed(x))==x

The Liskov Substitution Principle says that it's ok to modify the behaviour of in a derived class, provided the correctness of the program does not change. It imposes restrictions on the changes you make in the derived classes.

  • Thanks for your answer. So if Jet is violating LSP doesn't that demonstrate the huge difficulty, almost incompatibility, between inheritance and LSP? If a programming design book can't even give an example which doesn't break this design principle, what hope is there? Isn't one of the fundamental drivers of inheritance - to override the parent class's behaviour - completely at odds with the principle of LSP? – Andy Birchall Jun 27 '14 at 13:10
  • No, it's not at odds. Overriding behaviour in subclasses is indeed a fundamental part of OOP. LSP is a guideline for using it wisely. – S.L. Barth is on codidact.com Jun 27 '14 at 13:16
  • Ok thanks. You've answered my second question but not the first, i.e. doesn't this demonstrate the huge difficulty with not violating LSP? I would say a **lot** of inheritance examples, similar to the one above, given in reference books, break LSP in a similar manner. So it seems to me people learning the basics of OOP are being taught incorrect and bad use of inheritance. – Andy Birchall Jun 30 '14 at 11:17