gpt4 book ai didi

c# - Liskov 替换原则与普通继承有何不同?

转载 作者:行者123 更新时间:2023-11-30 22:51:44 26 4
gpt4 key购买 nike

我想了解 Liskov 替换原则。但我无法确定 Liskov 替换原则与正常继承有何不同。下面的代码是关于普通继承的。我应该如何处理下面的代码才能说我的代码遵循 Liskov 替换原则

    public class ClassA
{
public virtual void MethodA()
{
Console.WriteLine("-----------------ClassA.MethodA---------------------");
}

public virtual void MethodB()
{
Console.WriteLine("-----------------ClassA.MethodB---------------------");
}
}

public class ClassB: ClassA
{
public override void MethodA()
{
Console.WriteLine("-----------------ClassB override ClassA.MethodA---------------------");
}
}

最佳答案

这是一个常见的定义:

https://www.tomdalling.com/blog/software-design/solid-class-design-the-liskov-substitution-principle/

The Liskov Substitution Principle (LSP): functions that use pointers to base classes must be able to use objects of derived classes without knowing it.

这里有一个更严谨的解释:

https://en.wikipedia.org/wiki/Liskov_substitution_principle

..Liskov 替换原则 (LSP) 是子类型关系的特定定义,称为(强)行为子类型,最初由 Barbara Liskov 在 1987 年题为数据抽象和层次结构的 session 主题演讲中引入。它是一种语义关系,而不仅仅是句法关系,因为它旨在保证层次结构中类型(尤其是对象类型)的语义互操作性。 Barbara Liskov 和 Jeannette Wing 在 1994 年的一篇论文中简要描述了该原理如下:

子类型要求:

设 ϕ ( x ) 是关于类型 T 的对象 x 的可证明属性。
那么对于类型 S 的对象 y 来说 ϕ ( y ) 应该为真,其中 S 是 T 的子类型。

Liskov 原则对更新的面向对象编程语言中采用的签名施加了一些标准要求(通常在类级别而不是类型级别;请参阅名义与结构子类型以了解区别):

  • 子类型中方法参数的逆变。
  • 子类型中返回类型的协方差。
  • 子类型的方法不应抛出新异常,除非这些异常本身是父类(super class)型方法抛出的异常的子类型。

除了签名要求外,子类型还必须满足一些行为条件。这些在类似于契约设计方法的术语中进行了详细说明,从而导致对契约如何与继承交互的一些限制:

  • 不能在子类型中加强先决条件。
  • 不能在子类型中弱化后置条件。
  • 父类(super class)型的不变量必须保留在子类型中。
  • 历史约束(“历史规则”)。对象被认为只能通过它们的方法(封装)进行修改。因为子类型可能会引入父类(super class)型中不存在的方法,所以这些方法的引入可能会允许子类型中的状态更改,而这在父类(super class)型中是不允许的。历史约束禁止这样做。

问:你的例子符合吗?

答:我不这么认为。因为 A.MethodA() 在语义上与 B.MethodA() “不同”。 B 类未通过 The Duck Test .

我提出这个反例:

public class ClassA {
public virtual void MethodA() {
Console.WriteLine("ClassA.MethodA");
}

public virtual void MethodB(){
Console.WriteLine("ClassA.MethodB");
}
}

public class ClassC: ClassA {
public void MethodC() {
Console.WriteLine("ClassC.MethodC");
}
}

这也是为什么 LSP “等同于”继承的一个很好的例子。

关于c# - Liskov 替换原则与普通继承有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58897704/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com