Liskov 替换原则指出:
超类型的不变量必须保留在子类型中。
我对这个原理和多态性的交集特别感兴趣。但实际上,特别是子类型多态性,参数多态性和 Haskell 类型类似乎就是这种情况。
所以,我知道函数是子类型,当它们的参数是逆变的并且它们的返回类型是协变的。我们可以假设方法只是带有隐式“self”参数的函数。但是,这似乎暗示如果子类覆盖父类的方法,则它不再是子类型,因为其中一个方法不再是子类型。
例如。采用以下伪代码:
class Parent:
count : int
increment : Parent -> ()
{
count += 1
}
class Child inherits Parent:
increment : Child -> ()
{
count += 2
}
所以回到 LSP:我们可以说即使这两个不遵循严格的子类型关系,属性 也Parent.increment()
应该成立吗?Child.increment()
更一般地说,我的问题是:子类型化规则如何与多态函数的更具体的参数接口,以及将这两个概念结合在一起的正确思考方式是什么?