首页
学习
活动
专区
圈层
工具
发布

了解LSP
EN

Stack Overflow用户
提问于 2014-02-26 21:02:06
回答 1查看 217关注 0票数 1

读完这篇post后,我想我基本上理解了LSP和大多数例子,但我不能说我从我的经验中100%确定继承的例子,因为似乎许多例子确实违反了LSP,而且在重写行为时似乎很难不这样做。

例如,考虑下面的简单继承演示,取自Head First Object Oriented Analysis & Design。他们是否违反了Jet子类的LSP?

代码语言:javascript
复制
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吗?

例如。

代码语言:javascript
复制
void takeAirplane(Airplane airplane) { 
    airplane.setSpeed(10);
    assert airplane.getSpeed()==10;
}

如果向takeAirplane传递一个对Jet对象的引用,这显然会失败。在我看来,当“重写超类的行为”时,很难不违反LSP,但这是继承的主要/理想特性之一!

有人可以解释或帮助澄清这一点吗?我是不是遗漏了什么?

EN

回答 1

Stack Overflow用户

发布于 2014-06-26 18:59:55

根据Wikipedia的说法

利斯科夫替换原理指出,在计算机程序中,如果S是T的子类型,则类型T的对象可以被类型S的对象替换(即,类型S的对象可以替换类型T的对象),而不改变该程序的任何期望的属性(正确性、执行的任务等)。

在Jet的例子中,它的速度是LSP的两倍,这违反了LSP-它没有通过后置条件setSpeed(getSpeed(x))==x

Liskov替换原则说,只要程序的正确性不变,在派生类中修改的行为是可以的。它对您在派生类中所做的更改施加了限制。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22042237

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档