读完这篇文章后,我想我主要了解 LSP 和大多数示例,但我不能说我是 100% 确定从我对许多继承示例的经验来看,因为似乎很多示例确实违反了 LSP,而且似乎很难当覆盖行为时不要。
例如,考虑以下简单的继承演示,取自Head First Object Oriented Analysis & Design。他们是否违反了 Jet 子类的 LSP?
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);
}
}
使用对基类 Airplane 实例的引用的客户端在设置速度后可能会惊讶地发现它在传递一个 Jet 对象的实例后是预期速度的两倍。Jet 是不是改变了 setSpeed() 方法的后置条件,从而违反了 LSP?
例如
void takeAirplane(Airplane airplane) {
airplane.setSpeed(10);
assert airplane.getSpeed()==10;
}
如果 takeAirplane 传递了对 Jet 对象的引用,这显然会失败。在我看来,在“覆盖超类的行为”时很难不违反 LSP,但这是继承的主要/理想特性之一!
有人可以解释或帮助澄清这一点吗?我错过了什么吗?