【问题标题】:Why does this solution to the "Circle-ellipse" violate the "Liskov Substition Principle"?为什么“圆椭圆”的这种解决方案违反了“里氏替换原则”?
【发布时间】:2018-03-11 12:32:11
【问题描述】:

Circle-Ellipse Problem 中有一个违反里氏替换原则的好例子。

这是a popular SO answer 中的措辞(尽管是矩形和正方形):

在数学中,SquareRectangle。实际上,它是矩形的特化。 “is a”让你想用继承来建模。但是,如果在代码中您将Square 派生自Rectangle,那么Square 应该可以在您期望Rectangle 的任何地方使用。这会导致一些奇怪的行为。

想象一下,您的 Rectangle 基类上有 SetWidthSetHeight 方法;这似乎完全合乎逻辑。但是,如果您的 Rectangle 引用指向 Square,则 SetWidthSetHeight 没有意义,因为设置一个会更改另一个以匹配它。在这种情况下,Square 未能通过 Rectangle 的 Liskov 替换测试,并且 Square 从 Rectangle 继承的抽象是一个糟糕的抽象。

我的问题是 - 给定一个解决方案,我们在 Square 中覆盖 setWidth,实现将 widthheight 设置为相同的值,为什么它仍然违反语言服务提供商?

【问题讨论】:

    标签: oop liskov-substitution-principle


    【解决方案1】:

    它确实违反了它,因为您承诺setWidth() 将设置宽度,setHeight() 将设置高度。 Square 会破坏 Rectangle 的这个(隐式)承诺。

    【讨论】:

    • 谢谢。但是任何人都可以争辩说没有这样的隐含承诺,不是吗?它在哪里?它是从方法名称中暗示的吗?
    • 是的,名字就暗示了。如果您设置矩形的高度,任何人都非常清楚您的意思,您不同意吗?我想你可以将方法命名为setWidthAndSometimesHeight(),这样就可以了。但我认为你觉得那会非常奇怪..
    • 最好使用SquareDecoratorRectangle 类来提供Square 功能吗?
    • 我不会称它为装饰器,因为它并没有真正保留原始功能。我可能会创建一个与Rectangle 根本没有共同祖先的Square。这取决于用例。
    猜你喜欢
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 2018-06-27
    • 2015-02-15
    • 1970-01-01
    • 2017-07-26
    • 1970-01-01
    • 2015-01-01
    相关资源
    最近更新 更多