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?