如果重写方法返回不同的值,是否违反了Liskov原则?

shi*_*s19 3 c# oop solid-principles

下面是我的基类,它有ReturnAddress方法,返回'地址一',在子类中重写覆盖返回'地址二'的相同方法.

public class Base     
{         
     public virtual string ReturnAddress()        
     {             
         return "Address one";         
     }    
 }    


public class Derived : Base     
{                  
    public override string ReturnAddress()         
     {             
        return "Address Two";         
     }
}

//Object declaration for base and derived

Base base = new Base();

Derived der = new Derived();

var result = der.ReturnAddress(); // will return "Address Two"
but if we replace der object with base object 

var result = base.ReturnAddress(); //Will return "Address One"
Run Code Online (Sandbox Code Playgroud)

因此父对象无法替换子对象.

我想知道这是破坏Liskov原理的例子吗?

Ser*_*rvy 10

当您将子对象视为父对象时,LSP不会声明子对象将始终与父对象完全相同.如果是这种情况,那么继承对象是没有目的的.

相反,重点是您可以将Base对象视为Base对象或从其派生的任何对象.无论实际对象实例是类型Base还是类型,代码都应该工作Derived.现在,如果你的代码失败,如果Address Two返回,并且它希望 Address One返回,那么你将破坏LSP.如果您的代码无论返回哪个字符串都能正常工作,那么返回一个字符串就足够了,那么您就可以完成LSP了.

LSP声明您应该能够用另一个对象替换一种类型的对象,"不改变该程序的任何所需属性"(取自维基百科页面).那些理想的属性可能是"具有返回字符串的属性",或者它可能是"具有返回'Address One'的属性".您认为对该对象"期望"的内容决定了LSP是否被违反.

  • 严格意义上,LSP涵盖*"行为"*.这里的区别是*值/结果*不同,而不是*"行为"*.(我相信OP希望在两者之间划清界线.) (3认同)
  • @ user2864740它声明你应该能够用另一个对象替换一种类型的对象,"不改变该程序的任何所需属性"(取自维基百科页面).那些理想的属性可能是"具有返回字符串的属性",或者它可能是"具有返回'Address One'的属性".您认为该对象"理想"的内容决定了LSP是否适用于此. (2认同)
  • "理想的"由定义的行为覆盖,而不是类型系统. (2认同)