如果Liskov替换原则被违反,我该怎么办?

时间:2015-04-23 07:22:45

标签: java c# c++ oop liskov-substitution-principle

Liskov替换原则(LSP)声明如果对象o1是S的类型并且它可以替换为T类型的对象o2而不违反其所有用户的原始行为,那么S是T的子类型。

用于显示LSP违规的常见示例是Rectangle及其派生类型Square。争论的焦点是,虽然Square似乎是Rectangle的子类型,但Square的某些行为与Rectangle不同。结论是Square不能是LSP的Rectangle子类型。

我发现的所有解释都在那里结束,我发现它没有帮助。我想知道如果我有这个问题该怎么办?创建不是T的子类型的S,然后是什么?我有什么解决方案可以解决它?

有人可以给我一个悬而未决的问题的答案吗?

编辑:不是在这里详细说明这个例子,我建议你参考article

5 个答案:

答案 0 :(得分:2)

如果您无法建立&#39,则可以使用'有' ' USES' 关系;是A' 的关系。

这意味着不是让B类继承自A类,而是让B类包含A类的实例。这也是避免A类和B类之间紧密耦合的良好编码实践。

答案 1 :(得分:1)

这个问题在Scott Meyers的书“Effective C ++ 3rd Edition”,Addison Wesley 2005年5月中进行了回顾。在第6章,第32项。

Meyers为Rectangle创建了示例类,为Square继承了第一个类,并使用断言广泛讨论了出现的问题。

该项目的结论是:

“公共继承意味着”是-a。“适用于基础的一切 类也必须适用于派生类,因为每个派生类 class对象是一个基类对象。“

目前可以在互联网上找到或购买这本书。

答案 2 :(得分:0)

LSP是“is-a”关系的更精确定义,如果您违反LSP的类不是从基类派生的合适候选者。这是一个信号,表明你的设计出了问题。

值得注意的两点:违反LSP将破坏基类而不是派生类,这在遗留代码中非常危险,只需要很少的测试覆盖率,这种关系具有明确的“is-a”关系数学世界(如方形和矩形)他们可能不会在您的应用程序域中共享该关系。

答案 3 :(得分:0)

您可以将公共属性提取到接口或抽象类型中,并将其用作基础。差异仍然可以在派生类型中实现。

这样就可以保持你的IS关系。

答案 4 :(得分:0)

从LSP和rectange / square示例中学到的教训是, IS_A 与数学或生物学或任何看似明显 IS_A 的直觉无关。

IS_A 只是一种行为关系。 Square在OOP中不是矩形,因为它没有相同的行为。但矩形具有与方形相同的行为加上一些额外的不违反任何方形行为的行为。因此,在OOP矩形 IS_A 方形中,即使它违背数学和直觉,也很有意义地实现它。