Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop Liskov替代原理违反_Oop_Solid Principles_Liskov Substitution Principle - Fatal编程技术网

Oop Liskov替代原理违反

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

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

假设以下类层次结构:

  • 基本抽象类-
    AnimalWithFur
    。它具有一个只读属性
    furColor
    ,该属性在后续操作中被重写
  • 基类的后继类-
    Cat
    ,它覆盖
    furColor
    并返回灰色
  • Cat的后继者-
    Tiger
    ,它覆盖
    furColor
    ,并返回条带
  • 然后,我们声明一个方法,其参数类型为
    Cat
    not
    AnimalWithFur
    )。

    向该方法发送
    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的情况是否违反了规则有什么看法?我不完全同意你关于类层次结构的看法,但即使你说了这些话——我的代码只是关于一个示例,它不是设计为最好的解决方案:)对我来说,理解现有的、广泛使用的示例并与之进行比较是很容易的。不过,我喜欢你关于作文的笔记。好话