2

你可以有一个超类 Shape,Square 和 Rectangle 是两个子类,但是你可以有 Square 子类 Rectangle,因为 Square 是一个四边相等的特殊 Rectangle?

我试图用一个原则来检验,只要使用超类,它应该可以被它的子类替换,但如果使用子类,它可能无法被它的超类替换。看起来很好,但我总觉得 Square 不能是 Rectangle 的孩子,因为某种原因?谁能给我一些启示?

4

1 回答 1

4

您指的是Liskov 替换原则

可替代性是面向对象编程的一个原则。它指出,在计算机程序中,如果 S 是 T 的子类型,则类型 T 的对象可以替换为类型 S 的对象(即,类型 S 的对象可以替换类型 T 的对象)而不改变任何该程序的理想属性(正确性、执行的任务等)。

具体到您的问题:

违反 LSP 的典型示例是从 Rectangle 类派生的 Square 类,假设宽度和高度都存在 getter 和 setter 方法。Square 类始终假定宽度与高度相等。如果在需要 Rectangle 的上下文中使用 Square 对象,则可能会发生意外行为,因为 Square 的尺寸不能(或者更确切地说不应该)单独修改。这个问题不容易解决:如果我们可以修改 Square 类中的 setter 方法,使它们保持 Square 不变量(即,保持尺寸相等),那么这些方法将削弱(违反)Rectangle setter 的后置条件,即声明尺寸可以独立修改。像这样的违反 LSP 的行为在实践中可能是也可能不是问题,取决于使用违反 LSP 的类的代码实际期望的后置条件或不变量。可变性是这里的一个关键问题。如果 Square 和 Rectangle 只有 getter 方法(即它们是不可变对象),则不会发生违反 LSP 的情况。

在简单的英语中,您不能在需要 Rectangle 的地方使用 Square,因为 Square 具有 Rectangle 没有的行为。如果有人尝试使用他们认为应该是 Rectangle 的实例,但它实际上是 Square 的实例,他们可能会设置 Width 并惊讶于 Height 自动更改(意外的副作用)。

于 2012-07-12T04:29:11.863 回答