首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从矩形派生正方形是否违反了利斯科夫的替换原理?

从矩形派生正方形是否违反了利斯科夫的替换原理?
EN

Stack Overflow用户
提问于 2009-06-23 03:39:42
回答 8查看 17.5K关注 0票数 70

我对设计和学习设计原则是个新手。

它说,从矩形派生正方形是违反利斯科夫替换原则的经典例子。

如果是这样的话,正确的设计应该是什么?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2009-06-23 03:54:23

我相信理由是这样的:

假设您有一个接受矩形并调整其宽度的方法:

代码语言:javascript
运行
复制
public void SetWidth(Rectangle rect, int width)
{
    rect.Width = width;
}

假设这个测试将通过,这应该是完全合理的,因为什么是矩形:

代码语言:javascript
运行
复制
Rectangle rect = new Rectangle(50, 20); // width, height

SetWidth(rect, 100);

Assert.AreEqual(20, rect.Height);

..。因为更改矩形的宽度不会影响其高度。

但是,假设您从Rectangle派生了一个新的Square类。根据定义,正方形的高度和宽度始终相等。让我们再试一次这个测试:

代码语言:javascript
运行
复制
Rectangle rect = new Square(20); // both width and height

SetWidth(rect, 100);

Assert.AreEqual(20, rect.Height);

该测试将失败,因为将正方形的宽度设置为100也会改变其高度。

因此,从矩形派生Square违反了Liskov的替换原则。

" is -a“规则在”现实世界“中是有意义的(正方形绝对是一种矩形),但在软件设计的世界中并不总是如此。

编辑

为了回答你的问题,正确的设计应该是Rectangle和Square都派生自一个公共的"Polygon“或"Shape”类,该类不强制执行任何关于宽度或高度的规则。

票数 68
EN

Stack Overflow用户

发布于 2009-06-23 04:00:16

答案取决于可变性。如果矩形和正方形类是不可变的,那么Square实际上是Rectangle的一个子类型,从second派生first是完全可以的。否则,RectangleSquare都可以公开不带变形器的IRectangle,但是从另一个类型派生一个类型是错误的,因为这两个类型都不是另一个类型的子类型。

票数 89
EN

Stack Overflow用户

发布于 2009-06-23 04:11:26

我不同意从矩形派生正方形必然违反LSP。

在Matt的例子中,如果你的代码依赖于宽度和高度是独立的,那么它实际上就违反了LSP。

但是,如果你可以在不违反任何假设的情况下,在代码中的任何地方用矩形替换正方形,那么你就没有违反LSP。

因此,它实际上归结为抽象矩形在您的解决方案中意味着什么。

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

https://stackoverflow.com/questions/1030521

复制
相关文章

相似问题

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