【发布时间】:2019-03-12 13:51:02
【问题描述】:
我很困惑。我偶然发现了签名规则(B.Liskov 在她的作品中也提到过),其中指出:
论点的逆变性。 m1 和 m2 的数量相同 论据。如果m1的参数类型列表是a,m2 是 b,然后是 ∀i 。 ai bi //表示a是b.
来自其他教材:
对于函数类型 DY→CY 成为(即,可替代)的子类型 DX→CX ,我们必须在结果类型上是协变的,但在 参数类型!
那么,如果我只使用相同类型的参数和返回类型,这是否意味着我永远不会进行正确的子类型化?我不明白使用相同类型是否也很重要,即当我对父类和子类方法参数使用相同类型时,这是逆变的吗?
换句话说,由于 c# 不允许参数逆变,这是否意味着我的代码从不兼容 LSP?当我读到 LSP 要求参数必须是逆变的..
class Person
{
}
class Employee: Person
{
}
class PersonRegister
{
GetJobTitle(Employee e) {return e.JobTitle;}
}
class DeriverRegister: PersonRegister
{
GetJobTitle(Person p) //contravariance, using less derived type, cannot be done in C#
}
如果例如,这将如何工作较少派生的类型没有所需的字段,在此示例中是 JobTitle?这是 Employee 的财产,但必须是 Person 的财产。
【问题讨论】:
-
“我不明白是否使用相同的类型也很重要” - 在大多数正式的上下文中,如果 a 和 b 是相同的类型,“a 是 b 的子类型”是正确的,如果那是你的在问?当我们希望排除 a 和 b 是同一类型时,可以使用短语“strict subtype”。
-
@Damien_The_Unbeliever 基本上是的。 LSP 的指导方针说参数必须是逆变的。这是否意味着在父母和孩子中使用相同的类型是令人满意的并且符合要求?
-
如果您在方法定义中声明了
param1的类型,那么您使用GetJobTitle(param1)的示例会更有帮助。 -
@JohnWu 好的,定义的类型将是 Employee,因此 Person 是较少派生的类型,因此根据逆变规则是合法的。
标签: c# oop inheritance types subtyping