Oop Liskov替代原理违反
从 Liskov的行为亚型概念定义了 对象的可替代性;也就是说,如果S是T的一个子类型,那么 程序中T类型的对象可以替换为S类型的对象 不改变该程序的任何期望属性(例如。 正确性) 假设以下类层次结构:Oop Liskov替代原理违反,oop,solid-principles,liskov-substitution-principle,Oop,Solid Principles,Liskov Substitution Principle,从 Liskov的行为亚型概念定义了 对象的可替代性;也就是说,如果S是T的一个子类型,那么 程序中T类型的对象可以替换为S类型的对象 不改变该程序的任何期望属性(例如。 正确性) 假设以下类层次结构: 基本抽象类-AnimalWithFur。它具有一个只读属性furColor,该属性在后续操作中被重写 基类的后继类-Cat,它覆盖furColor并返回灰色 Cat的后继者-Tiger,它覆盖furColor,并返回条带 然后,我们声明一个方法,其参数类型为Cat(notAnimalWithFu
AnimalWithFur
。它具有一个只读属性furColor
,该属性在后续操作中被重写Cat
,它覆盖furColor
并返回灰色Tiger
,它覆盖furColor
,并返回条带Cat
(notAnimalWithFur
)。向该方法发送
Tiger
实例是否违反了实数形式的L?简短回答:不一定。如果你告诉我的话,我会说不。对我来说,关键是你不要说想象中的新方法应该做什么
你可能会认为你在新方法中需要的行为比关注类层次结构更重要。
一种方法是从传入的实例/参数中为新方法所需的行为定义一个接口然后,您可能希望传递到该方法中的任何类都可以实现该接口,并且您可以打破继承层次结构的顾虑,转而关注行为的一致性。严格地说,是的。利斯科夫的维基文章总结说: “…在a程序中…不改变该程序的任何理想特性” 如果你回顾一下Barbara Liskov的著作,它的措辞就更严格了,3.3。 类型层次结构: 如果对于类型S的每个对象o1,有一个类型T的对象o2,那么对于根据T定义的所有程序p,当o1被o2替代时,p的行为保持不变 (Empahsis矿) 因此,如果将
Cat
的一个实例替换为另一个执行不同操作的实例,即返回stripped not grey,那么这就是原始意义上的Liskov冲突,因为可以很容易地定义依赖于灰色的程序,如下所示:
program(Cat c){
println(c.furColor);
}
如果您将一个老虎
代替猫
传递给该程序,则该程序的行为将发生变化
但是,按照应用LSP的正常方式,如果没有添加额外的先决条件或后决条件,则不会违反LSP。这是一个更加实用、学术性较低的定义,因为人们承认,当用一种具体类型的实例替换另一种实例时,确实打算改变程序的行为,同时保持该程序的理想属性。因此,假定客户端代码可以像处理任何其他颜色一样处理剥离,并且程序的“理想”属性不需要灰色,那么它就不会违反。您的问题很好地描述了为什么要使用类组合而不是类继承。首先,你的代码是不合逻辑的-
Tiger
在你的意义上不是一个Cat
,Tiger
是Cats家族中的一员。
从代码的角度来看,重写并完全替换父类的行为是一个糟糕的设计,这实际上是liskov替换冲突-您的Cat
类意味着使用一些具体的颜色定义了Cat,应用程序希望分别使用它,但您正在使用不一致的类型覆盖它并更改行为。
如果您能正确描述类型层次结构,您将拥有抽象类型Cat
,而不实现furColor,类型Tiger
和HomeCat
,但是HomeCat
可以有不同的颜色,不是吗
如果您想获得LS违规的简单示例,例如:
您正在使用自定义实现扩展
List
接口,返回的大小始终为10,但内部对象的数量不同。每个普通应用程序都希望使用list using for语句,但会有不可预测的行为,因为您违反了LS原则,并且list对象的行为不符合预期。将参数类型重写为AnimalWithFur会改变什么吗?不会,因为属性furColour在AnimalWithFur上。你仍然在用老虎来代替猫,因为我不得不假设,如果你接受LSP,你是在替代,你只有两种具体类型;猫和老虎。它甚至可能与属性的实际定义无关,如果它改变了程序的理想属性,那就是违反了LSP。LSP现在有不同的风格了吗?那太方便了;它允许我们通过同时说是和否来回答LSP问题。一切都违反了严格的LSP,但大多数都遵循正常的LSP。@jaco0646我引用了原始论文的原文。如果子类型改变了cat的颜色,并且改变了程序的行为,那么这就是违反。维基被淡化了,用“改变想要的属性”代替“不变”。这是两个。告诉我,你对OP的情况是否违反了规则有什么看法?我不完全同意你关于类层次结构的看法,但即使你说了这些话——我的代码只是关于一个示例,它不是设计为最好的解决方案:)对我来说,理解现有的、广泛使用的示例并与之进行比较是很容易的。不过,我喜欢你关于作文的笔记。好话