例如,我们具有以下结构:
class Base
{
[pure]
public virtual bool IsValid(/*you can add some parameters here*/)
{
//body
}
}
class Child : Base
{
public override bool IsValid(/*you can add some parameters here*/)
{
//body
}
}
您能否用不同的正文填充
Base::IsValid()
和Child::IsValid()
,但又不要与LSP冲突?假设这只是分析的方法,我们不能更改实例的状态。我们能做到吗?
我对任何示例都感兴趣。
我尝试了解虚拟(实体) bool 方法在一般情况下是否为反模式。
最佳答案
LSP的思想不禁止子类的多态性。相反,它强调允许更改的内容和不允许更改的内容。
通常,这意味着:
前两个项目符号定义非常明确。 “不变式”更多是一个理性的问题。例如,如果实时环境中的某个类要求其所有功能在某个恒定时间内运行,则其子类型中的所有重写功能也必须遵守该要求。
在您的情况下,IsValid()表示某些内容,并且“所有内容”必须保留在所有子类型下。例如,假设您的Base类定义了一种产品,并且IsValid()告知该产品是否有效出售。使每种产品有效的确切原因可能有所不同。例如,必须设置其价格才能对销售有效。但是, child 产品还必须经过电气测试,然后才能出售。
在此示例中,我们保留所有要求:
您可以得到更多的解释here。
===
编辑-根据注释进行一些其他解释
多态的整体思想是,每个子类型都以不同的方式完成相同的功能。 LSP并不违反多态性,但描述了应注意的多态性。
特别是,LSP要求在代码需要
Child
的情况下,可以使用任何子类型Base
,并且对Base
所做的任何假设都适用于他的任何Child
。在上面的示例中,IsValis()
并不表示“有价格”。相反,这恰好意味着:产品有效吗?在某些情况下,有一个价格就足够了。换句话说,它还需要进行电力检查,而在另一些情况下,它可能还需要一些其他属性。如果Base
类的设计者不要求通过设置价格来使产品变为有效,而是将IsValid()
留作单独的测试,则不会发生违反LSP的情况。哪个例子会造成这种侵犯?一个示例,询问一个对象是否为IsValid()
,然后调用基类的函数,该函数不应更改有效性,并且该函数将Child
更改为不再有效。这违反了LSP的历史记录规则。这里其他人提供的已知示例是正方形,作为矩形的子级。但是,只要相同的函数调用序列不需要特定的行为(再次-没有定义设置价格使产品有效;在某些类型中恰好是这种方式)-LSP被保留。关于oop - 在不中断LSP的情况下覆盖虚拟 bool 纯方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50046333/