Liskov Substitution Principle是否也适用于实现接口的类?

use*_*278 3 design-patterns liskov-substitution-principle

1)LSP是否也适用于接口,这意味着我们应该能够使用实现特定接口的类并仍能获得预期的行为?

2)如果确实如此,那么为什么编程接口被认为是好事(顺便说一句 - 我知道对接口的编程会增加松散耦合),如果反对使用继承的主要原因之一是由于不存在风险遵守LSP?也许是因为:

a)松散耦合的好处超重了不遵守LSP的风险

b)与继承相比,类(实现接口)不会附加到LSP的可能性要小得多

谢谢

jga*_*fin 6

LSP是否也适用于接口,这意味着我们应该能够使用实现特定接口的类并仍然获得预期的行为?

LSP适用于合同.合同可以是类或接口.

如果确实如此,那么为什么编程接口被认为是一件好事(顺便说一句 - 我知道对接口进行编程会增加松散耦合),如果反对使用继承的主要原因之一是由于不遵守的风险LSP?也许是因为:

它不是关于接口或类.这是违反合同的.假设你Break()IVehicle(或VehicleBase)中有一个方法.任何人打电话都会期望车辆坏掉.如果其中一个实现没有破坏,想象一下这个惊喜.这就是LSP的全部意义所在.

a)松散耦合的好处超重了不遵守LSP的风险

EHH?

b)与继承相比,类(实现接口)不会附加到LSP的可能性要小得多

EHH?

您可能希望阅读我的SOLID文章以更好地理解该原则:http://blog.gauffin.org/2012/05/solid-principles-with-real-world-examples/

更新

详细说明 - 使用继承虚拟方法可能会使用私有成员,覆盖这些虚方法的子类无法访问这些成员.

是.非常好.成员(字段)应始终受到保护(=声明为私有).只有定义它们的类才真正知道它们的值应该是什么.

此外,派生类从父级继承上下文,因此可以通过将来对父类等的更改来打破.

这违反了开放/封闭原则.即通过改变行为来改变类合同.类应该扩展而不是修改.当然,它不可能一直存在,但改变不应该使类的行为不同(除了错误修正).

因此,我觉得让子类尊重合同比让实现接口的类更难以实现它更难

有一个共同的原因,为什么延伸通过继承是困难的.这是因为这种关系不是真正的is-a关系,而是开发人员只想利用基类功能.

那是错的.那么最好使用成分.