[英]Why weakening a precondition does not violate Liskov substitution principle
[英]Does omitting super() and/or *weakening* preconditions violate the Liskov Substitution Principle?
我最近一直在深入研究一些SOLID设计原则,我从一个来源获得的一些信息最初对我有意义,但基于我已经能够找到的针对thr LSP的严格定义,它似乎就是这样的信息可能不正确。 信息具体是:
1)在重写方法上没有回调到super()会违反LSP(或者至少会打开你的违规行为),因为基类的行为可能会在某些时候发生变化,而你的子类可能会以导致子类不再可替代父类。 这对我来说似乎有意义,但是如果有人可以详细说明/给出一些关于什么时候不适合不回电话的信息那就太棒了。
2)子类的限制不应低于父类。 示例是:如果您的父类只接受正整数,那么您创建一个接受正负int的子类。 因此,孩子应该在父母的位置上工作正常,但在这种情况下,孩子不能委托给超级。
我认为这是有道理的,但LSP上的信息似乎恰恰相反:孩子无法强化前提条件。 两者似乎都对我有意义,但利斯科夫只是说前提条件不能加强,后置条件不能削弱。 有人可以帮助我这个吗?
1)情况,当不适合不回电话时
通常(但并非总是)这种情况意味着类层次结构设计出了问题。
如果子方法接受正确的输入类型并返回正确的输出类型,则不调用超类实现不会违反LSP。 它只表明问题的可能性。
当你不调用super方法时,这是一个绝对有效的例子:
class Animal
void eat(Food food)
// Eat the food
class Cat extends Animal
void meow()
// Say meow
class AnimalOwner
Animal findAPet()
return new Animal()
class CatOwner
// we can return the subclass of Animal here
Cat findAPet()
return new Cat() // We don't need to use the parent implementation
这里CatOwner::findAPet()
返回一个Cat
(一个Animal
子类),这在LSP方面是有效的,我们不调用父实现。
请注意,调用父实现并不能保证您不会遇到与不调用它时相同的问题。
考虑这个例子:
class Child
Output doSomething()
parent = super::doSomething()
if parent->isNotGood():
return new OutputSubclass() // We called super, but we return
// something different, might be not safe
else:
return parent // We called super and return
// the same value, safe
2)“在子类型中不能加强先决条件”。 这也意味着前提条件(与输入参数相关的期望)可以保持不变或被削弱。 在你提到的例子中,前提条件实际上被削弱了,所以没有冲突:
Parent::doSomething(PositiveInteger value) // Only positive integers
Child::doSomething(Integer value) // Positive or negative integers,
// pre-condition is weaker
// (covers wider area of values)
不正确的是第一句话:“子类不应该比父母更少限制”。 当我们讨论前置条件(输入参数)时,子类可以减少限制,这就是示例中显示的内容。
Liskov替换原则要求您可以在期望基类型时使用子类型。 为此,您必须遵守基本类型的合同。 对于具有方法f,前提条件Pre,postcondition Post和不变I的基类B,这意味着
我会考虑显式调用基类实现代码气味(构造函数除外)。 使用te,plate方法模式 (或C ++中的非虚拟接口 )来强制执行基类合约要好得多。 在Python中,这看起来像:
class Base:
def publicMethod(self, x):
// do something
self.templateMethod(x)
// do something else
def templateMethod(self, x):
// has to be overriden by sub-classes
// it provides extension hooks, but
// publicMethod ensures that the overall
// functionality is correct
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.