首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Liskov替代原理、前提和抽象方法

Liskov替代原理、前提和抽象方法
EN

Stack Overflow用户
提问于 2016-12-04 21:22:20
回答 2查看 677关注 0票数 4

Liskov替代原则(LSP)说:

不能在子类型中加强先决条件。

在C#中,我可能会违反以下全部原则:

代码语言:javascript
复制
public class A 
{
      public virtual void DoStuff(string text)
      {
            Contract.Requires(!string.IsNullOrEmpty(text));
      }
}

public class B : A
{
      public override void DoStuff(string text)
      {
            Contract.Requires(!string.IsNullOrEmpty(text) && text.Length > 10);
      }
}

但是,如果A.DoStuff是一个abstract方法,会发生什么:

代码语言:javascript
复制
public class A 
{
      public abstract void DoStuff(string text);
}

public class B : A
{
      public override void DoStuff(string text)
      {
            Contract.Requires(!string.IsNullOrEmpty(text));
      }
}

现在A.DoStuff是无契约的。或者说它的合同是一切允许的。

那么,B.DoStuff的前提条件是否违反了Liskov替换原则?

EN

回答 2

Stack Overflow用户

发布于 2016-12-04 22:15:27

这取决于是如何定义契约的。

LSP是一个理论结构,它不依赖于特定的语言或实现,例如C#的“代码契约”特性。

合同的定义可以是:

  • 方法名
  • 方法参数名
  • 方法评语
  • 返回类型和方法参数类型
  • “显式”合同,如Contract.Requires

最后两个将由编译器进行验证。不过,前三个也可以是合同的一部分!请考虑以下示例:

代码语言:javascript
复制
public interface StuffContainer
{
    void Add(string text);

    // Removes a string that has previously been added.
    void Remove(string text);
}

Remove方法的名称和文档定义了一个明确的先决条件。在实现中验证要删除的字符串之前是否已被添加,并不违反LSP。验证字符串至少有5个字符将违反LSP。

票数 2
EN

Stack Overflow用户

发布于 2016-12-04 21:44:04

是的,你可以很容易地打破这个原则,不仅仅是在C#中。

它只规定:

子类型要求:设phi(x)是T型对象x的一个可证明的属性,则对于S类型的对象y,phi(y)应为真,其中S是T的一个子类型。

在您的示例中,类型B不满足提供处理短文本的方法DoStuff的特性,尽管它的超级类型A实现了它。所以这个原则被违反了。

这取决于程序员坚持这一原则。属性也可以是“它做正确的事情”,您可以很容易地通过拥有一个带有方法的错误实现的子类型来打破它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40963811

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档