读完这篇post后,我想我基本上理解了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,但这是继承的主要/理想特性之一!
有人可以解释或帮助澄清这一点吗?我是不是遗漏了什么?
发布于 2014-06-26 18:59:55
根据Wikipedia的说法
利斯科夫替换原理指出,在计算机程序中,如果S是T的子类型,则类型T的对象可以被类型S的对象替换(即,类型S的对象可以替换类型T的对象),而不改变该程序的任何期望的属性(正确性、执行的任务等)。
在Jet的例子中,它的速度是LSP的两倍,这违反了LSP-它没有通过后置条件setSpeed(getSpeed(x))==x
Liskov替换原则说,只要程序的正确性不变,在派生类中修改的行为是可以的。它对您在派生类中所做的更改施加了限制。
https://stackoverflow.com/questions/22042237
复制相似问题