Liskov替代原则(LSP)说:
不能在子类型中加强先决条件。
在C#中,我可能会违反以下全部原则:
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方法,会发生什么:
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替换原则?
发布于 2016-12-04 22:15:27
这取决于是如何定义契约的。
LSP是一个理论结构,它不依赖于特定的语言或实现,例如C#的“代码契约”特性。
合同的定义可以是:
Contract.Requires最后两个将由编译器进行验证。不过,前三个也可以是合同的一部分!请考虑以下示例:
public interface StuffContainer
{
void Add(string text);
// Removes a string that has previously been added.
void Remove(string text);
}Remove方法的名称和文档定义了一个明确的先决条件。在实现中验证要删除的字符串之前是否已被添加,并不违反LSP。验证字符串至少有5个字符将违反LSP。
发布于 2016-12-04 21:44:04
是的,你可以很容易地打破这个原则,不仅仅是在C#中。
它只规定:
子类型要求:设phi(x)是T型对象x的一个可证明的属性,则对于S类型的对象y,phi(y)应为真,其中S是T的一个子类型。
在您的示例中,类型B不满足提供处理短文本的方法DoStuff的特性,尽管它的超级类型A实现了它。所以这个原则被违反了。
这取决于程序员坚持这一原则。属性也可以是“它做正确的事情”,您可以很容易地通过拥有一个带有方法的错误实现的子类型来打破它。
https://stackoverflow.com/questions/40963811
复制相似问题