为什么参数类型泛化为覆盖时的方法特化?

Why is the parameter type generalized for method specialization on override?

我正在阅读的这本书刚刚介绍了包含、协变、逆变的概念及其对编程语言设计的影响。现在,在关于方法专业化的部分,我遇到了麻烦。

书中指出,当我们重写子类中的方法时,参数类型可能被泛化,结果类型可能被特化。然而,本书认为,对于未被覆盖但被继承的方法,另一种类型的方法特化正在发挥作用,其中参数类型是特化的,结果类型是通用的,因为我们可以将 self 关键字解释为参数:

"There is another form of method specialization that happens implicitly by inheritance. The occurrences of self in the methods of C can be considered of type C, in the sense that all objects bound to self have type C or a subtype of C. When the methods of C are inherited by C', the same occurrences of self can similarly be considered of type C'. Thus the type of self is silently specialized on inheritance (covariantly!)."

这是我的问题:我们不能将 self 关键字也视为重写方法中的协变参数吗?然后我们将以 this 关键字作为协变参数结束,即使我们刚刚确定,作为替换原则的结果,重写方法的参数需要是逆变的。我是不是忽略了什么?

感谢您的帮助!

编程语言中变体的实现

...when we override methods in subclasses, parameter types may be generalized (covariance), and result types may be specialized (contravariance)

尽管这可能是真的,但这取决于具体的语言,它是否实际实现了这个功能。我找到了 examples on wiki:

  • C++ 和 Java 仅实现协变 return 类型和方法 参数类型是不变的。

  • C# 没有实现任何一种变体(因此两者都是不变的)。

  • 有一个具有逆变参数类型和协变类型的语言 (Sather) 的示例 return - 这就是您提到的。

  • 然而,还有一个(Eiffel)具有协变 return & 参数类型,但这 可以 通常会导致运行时错误。

控制和“遗留”参数

There 也是一个很好的段落,将参数分为 控制参数 和“left-over” 参数。控制的是协变的,非控制的是逆变的。这是关于多种调度语言的,尽管您肯定指的是一种调度语言。但即使只有一个控制参数 (self/this).

这是一段话(我没有时间研究paper it is referring to,如果你有时间和post你的发现,请随意阅读):

Giuseppe Castagna[3] observed that in a typed language with multiple dispatch, a generic function can have some arguments which control dispatch and some "left-over" arguments which do not. Because the method selection rule chooses the most specific applicable method, if a method overrides another method, then the overriding method will have more specific types for the controlling arguments. On the other hand, to ensure type safety the language still must require the left-over arguments to be at least as general. Using the previous terminology, types used for runtime method selection are covariant while types not used for runtime method selection of the method are contravariant.

Conventional single-dispatch languages like Java also obey this rule: there only one argument is used for method selection (the receiver object, passed along to a method as the hidden argument this), and indeed the type of this is more specialized inside overriding methods than in the superclass.

问题

根据该段,我假设 self 参数本质上不是常规方法参数(可能是逆变的),因为 self 是另一种参数 - 控制参数 - 是协变的.

...even though we just established that, as a consequence of the substitution principle, arguments of overridden methods need to be contravariant.

嗯,好像不是全部。