违反里氏替换原则 [英] Liskov substitution principle violation

查看:71
本文介绍了违反里氏替换原则的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自维基百科

Liskov 的行为子类型概念定义了对象的可替代性;也就是说,如果 S 是 T 的子类型,那么程序中类型 T 的对象可以替换为类型 S 的对象不改变该程序的任何理想属性(例如正确性).

Liskov's notion of a behavioral subtype defines a notion of substitutability for objects; that is, if S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that program (e.g. correctness).

假设以下类层次结构:

  1. 基础抽象类 - AnimalWithFur.它有一个只读属性 furColor,在后继者中被覆盖.
  2. 基类的继承者 - Cat,它覆盖了 furColor 并返回 gray.
  3. Cat 的继承者 - Tiger,它覆盖了 furColor 并返回 striped.
  1. The base abstract class - AnimalWithFur. It has a read-only property furColor that is overridden in successors.
  2. Base class's successor - Cat, which overrides furColor and returns gray.
  3. Cat's successor - Tiger, which overrides furColor and returns striped.

然后我们声明一个带有 Cat 类型参数的方法(not AnimalWithFur).
向该方法发送 Tiger 实例是否违反了 SOLID 中的 L?

Then we declare a method with an argument of type Cat (not AnimalWithFur).
Is sending a Tiger instance to that method a violation of the L in SOLID?

推荐答案

严格来说,是的.Liskov的wiki文章总结说:

Strictly speaking, yes. The wiki article summation of Liskov says:

...在一个程序中...不改变那个程序的任何理想属性"

"...in a program...without altering any of the desirable properties of that program"

如果您回到 Barbara Liskov 的原始论文,它是字面上更严格的措辞,3.3.类型层次结构:

If you go back to the original paper by Barbara Liskov, it's literally stricter in its wording, 3.3. Type Hierarchy:

如果对于每个 S 类型的对象 o1 都有一个 T 类型的对象 o2 使得对于所有程序 P 定义在 T 中,P 的行为是不变的 当 o1 代替 o2 时

If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2

(Emahsis 我的)

(Empahsis mine)

因此,如果您将 Cat 的一个实例替换为另一个执行不同操作的实例,即返回 stripped 而非灰色,那么这就是原始意义上的 Liskov 违规,因为可以轻松定义程序这依赖于灰色,这里:

So if you replace an instance of Cat with another instance that does something different, i.e. returning stripped not grey, then that is a Liskov violation in the original sense, because a program could be easily defined that relies on the color being grey, here:

program(Cat c){
   println(c.furColor);
}

如果你传递一个 Tiger 代替 Cat,那个程序的行为将会改变.

The behaviour of that program will change if you pass it a Tiger in place of a Cat.

但是,在应用 LSP 的正常方式中,如果您没有添加额外的前置条件或后置条件,则不会违规.这是一个更实用、更不学术的定义,因为人们接受当用另一种具体类型替换一个实例时,您确实打算改变程序的行为,同时保持该程序的理想属性.因此,假设客户端代码可以像处理任何其他颜色一样处理剥离,并且程序的理想"属性不需要灰色,那么它就不会违反.

However, in the normal way LSP is applied, it is not a violation if you did not add extra preconditions or postconditions. This is a more practical, less academic definition as people accept that when replacing an instance of one concrete type with another you do intend to change the behaviour of the program while maintaining desirable properties of that program. So presuming the client code can handle stripped like any other colour, and grey was not required for a "desirable" property of the program then it does not violate.

这篇关于违反里氏替换原则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆