子类型的实际前提条件是通过组合(使用逻辑OR
)基类型的前提条件和子类型的前提条件来创建的,这使得生成的前提条件 限制较少。
子类型的实际后置条件是通过组合(使用逻辑AND
)基本类型的后置条件和子类型的后置条件来创建的,这使得生成的后置条件 更具限制性。
以下是加强前置条件和削弱后置条件的示例,因此违反了 LSP(链接):
假设您的基类与成员 int 一起使用。现在您的子类型要求该 int 为正数。这是强化的先决条件,现在任何以前使用负整数都可以正常工作的代码都被破坏了。
同样,假设相同的场景,但用于保证成员在被调用后为正的基类。然后子类型改变行为以允许负整数。对对象起作用的代码(并假设后置条件是一个正整数)现在被破坏了,因为后置条件没有得到支持。
a) 为什么当被覆盖的方法削弱了先决条件时,它也被认为是违反 LSP的,因为该方法可能使用基本类型的合约不可接受的参数。因此,我们不能声称违反了基本类型的合同,因此也违反了 LSP 吗?
b) 为什么当被覆盖的方法增强后置条件时,它也不被认为是违反 LSP的,因为调用此方法的客户端只会收到原始方法可能结果的子集。因此,我们不能声称违反了基本类型的合同,因此也违反了 LSP 吗?
例子:
基类后置条件保证方法的返回值在范围内1-10
,但随后子类型将后置条件更改为只允许返回值在范围内2-9
。现在,处理从此方法返回的对象的代码(并假设后置条件在一个范围内1-10
)被破坏了,因为后置条件没有得到支持。