2011-12-22 143 views
1

我有一个模型抽象类,它声明了一个项目列表。摘要有两个抽象类。其中你可以添加新的项目到列表和一个根本不使用该列表,但除此之外的模型抽象类的其他行为。在这种情况下,我可以违反LSP(Liskov替换)吗?

我声明了两种方法来添加和删除列表中的项目。很显然,无论何时我想使用这些方法,我都需要将模型抽象与其子类一起施放。

在这种情况下,我可以违反LSP (Liskov substitution principle)吗?或者有解决这个问题的办法吗?

+6

请给我们展示一些代码。它会更清晰。 – 2011-12-22 10:18:37

+0

这听起来像是上课不是要去这里的路。继承几乎总是唯一有意义的,如果你可以透明地用基类来代替派生类。 – helpermethod 2011-12-22 10:35:04

+0

违反Liskov替代原则几乎不是一个好主意,所以你必须有一个非常有力的论证来证明这一点。 – Jesper 2011-12-22 10:35:06

回答

1

我想你会违反LSP。

Wikipedia page for LSP(即永远是您的朋友):

“更正式地,里氏替换原则(LSP)是一种子类型关系的一个特定的定义,所谓的(强)行为子类型”

“行为子类型比在类型理论,这仅在参数类型和返回类型的协方差的逆变依赖定义函数典型亚型更强的概念。行为子类型是一般平凡不可判定”

看起来类似于你的情况:

“违反LSP是正方形类从一个矩形类派生,假设二者的宽度和高度存在获取和设置方法的典型例子。 Square类始终假设宽度与高度相等。如果在需要Rectangle的上下文中使用Square对象,则可能会发生意外的行为,因为Square的尺寸不能单独修改(或者不应该)。这个问题不容易修正:如果我们可以在Square类中修改setter方法,以便它们保留Square不变量(即保持尺寸相等),那么这些方法将削弱(违反)Rectangle设置器的后置条件,说明尺寸可以独立修改。 LSP的违规行为,像这样的,可能会或可能不会在实践中”

0

没学过LSP,但生病说这

有投一直是坏的(不太理想)OO设计的标志。

如果你想,你可以设置的东西太多,然后模型声明为正确的模型

同样适用于Java集合API

Collection coll = new ArrayList(); 
((List) coll).set(3,"sdf"); 

是代码,将工作,但只是写的不好

应该offcourse一直

List coll = new ArrayList(); 
coll.set(3,"sdf"); 

使用你想要的具体类型

0

我明白LSP上的问题,但在这里,它可能是这个问题解决了设计原因,Java有单继承和多接口。

一个类可以只扩展另一个类。在C++中,情况并非如此,超类中可能存在冲突的名称。多重继承也给出了一些理论类型问题。

所以你必须把一个方面变成一个接口,并且可以从一个实现一个或多个接口的抽象类扩展。

当Square从Rectangle延伸并实现WidthEqualsHeight时,LSP保持不变。

相关问题