2015-04-23 50 views
4

Liskov Substitution Principle(LSP)指出,如果一个对象o1是S的一种类型,并且它可以代替对象o2,而这个对象是一个T类型的对象,并且不违反其所有用户的原始行为,那么S是一个T的子类型。如果违反Liskov替代原则,我该怎么办?

用于显示LSP违例的常见示例是矩形及其派生类型Square。我们的观点是,虽然直觉上Square看起来是Rectangle的子类型,但是有一些与Rectangle不同的Square的行为。结论是,Square不能通过LSP来成为Rectangle的子类型。

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

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

编辑:我不是在这里详细说明这个例子,而是我把这个article转给你。

+3

'有一些与矩形不同的方形行为? – deviantfan

+0

这些差异是否与您的情况相关?如果没有,你仍然可以从矩形派生出正方形。 – Martze

+0

@deviantfan:'mySquare.Length = 5;'也设置宽度为5,而'myRectangle.Length = 5;'不宽度为5 – Jonny

回答

2

您可以使用“有一个”“使用”关系,如果你不能建立“是”关系。

这意味着,而不是从A类B类继承,你可以有B类包含A类的实例,这也是很好的编码习惯,以避免A类和B类

0

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

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

0

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

这样你保持你的IS关系。

1

这个问题是在这本书有效C++第三版斯科特迈尔斯,艾迪生韦斯利2005年5月在第6章,项目审查32.

有迈尔斯使得样本类矩形和类方形它继承了第一并广泛谈论使用断言引发的问题。

项目的结论是:

“公有继承意味着‘是一个适用于基础 类也必须适用于派生类’一切,因为每一个派生 类对象是一个基类对象。 “。

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

+0

与本书参考很好的搭配 – noobed

0

的教训,从LSP学习和rectange /平方的例子是,IS_A无关用数学或生物学或任何凭直觉显然IS_A看起来。

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

相关问题