为什么方矩形问题会破坏里氏替换?

问题描述 投票:0回答:1

里氏替换原则(LSP)对子类型提出了四项行为要求(直接来自维基百科):

  • 子类型中无法强化先决条件
  • 后置条件在子类型中不能被削弱
  • 子类型中的不变量不能被削弱
  • 历史约束(“历史规则”)。对象被认为只能通过其方法进行修改 [...]

有一个有点著名的方形-矩形(或圆形-椭圆形)问题会破坏 LSP,但我想了解它实际上破坏了哪些条件。

问题如下:我们有一个

Square
,其中 is-a
Rectangle
。我们可以设置
w
的宽度
h
和高度
Rectangle
,在
Square
的情况下,它们会被覆盖以同时修改宽度和高度(即
Square.setWidth
是实现将
w
h
设置为相同的值)。

现在,我们引入另一个类方法

squeeze
,它将
h
更改为
h/2
。如果在
Square
上调用此方法,则会违反
w==h
的不变量。

直观地说,我们会从上面打破不变条件,但问题似乎是我们在子类型中加强了一个不变量(原来的不变量只是

w,h >= 0
)。

我们也没有削弱后置条件。再说一次,如果有什么事情的话,我们必须加强后置条件,即在对

w==h
进行任何操作之后,
Square
不存在
Rectangle

我不明白先决条件有何相关性。

对于历史约束,我们只使用了类方法。

oop liskov-substitution-principle
1个回答
0
投票

如果将正方形视为矩形,则里氏替换原理就会出现问题,因为两者的行为不同。

如果将 5x5 矩形 的高度更改为 6,它将变成 5x6 矩形。如果你对一个正方形做同样的事情,它就会变成一个 6x6 的正方形。

因此,如果您有一个测试用例在更改高度后检查宽度(或面积),则两个形状之间的行为会有所不同。

© www.soinside.com 2019 - 2024. All rights reserved.