Square和Rectangle可以子类化Shape,但是Square子类可以是Rectangle吗?

时间:2012-07-12 04:23:32

标签: design-patterns

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

我尝试使用以下原则进行检查:每当使用超类时,它应该能够被其子类替换,但是如果使用子类,则可能无法被其超类替换。 。看起来很好,但我总觉得Square因某种原因不能成为Rectangle的孩子?谁能让我有所了解?

1 个答案:

答案 0 :(得分:3)

您指的是Liskov Substition Principle

  

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

特定于您的问题:

  

违反LSP的典型示例是Square类,它派生自Rectangle类,假设宽度和高度都存在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会自动更改(意外的副作用)。

相关问题