我想知道是否通常可以统一继承和参数多态性(“泛型”)的概念,特别是关于方差,还有他们必须如何(“语法”)和在哪里(使用站点/声明站点)被定义?
考虑这个观点:
S <: T
可以被视为协变行为,因为输入参数接受 T
也将接受S
. final
修饰符添加到类定义),就我所见,逆变是不可能的大多数情况考虑到两者之间似乎存在不可忽略的概念不匹配
String[] <: Object[]
)在某些语言中,可以看出两者可以很好地协同工作,例如
class Foo extends Ordered[Foo]
实现排序/比较行为。
最佳答案
通过协方差/逆变,通常意味着这一点。假设 X
, Y
, Z
是类型。进一步假设 a → b
表示参数类型为 a
的函数类型和类型 b
的结果. <:
表示子类型关系,或者可能是“一致性”的其他一些概念。 ⇒ 箭头读作“包含”。那么以下成立:
X <: Y ⇒ (Z → X) <: (Z → Y)
X <: Y ⇒ (Y → Z) <: (X → Z)
也就是说,函数类型构造函数对于结果类型(数据源)是协变的,对于参数类型(数据接收器)是逆变的。这是一个基本事实,您或多或少不能对此做任何太有创意的事情,例如反转箭头的方向。当然,您始终可以使用无方差代替协变或逆变(大多数语言都这样做)。
对象类型可以用函数类型进行规范编码,所以这里也没有太多的自由。每个类型参数表示数据源(协变)或数据接收器(逆变)或两者(变变)。如果它在一种语言中是合理且逆变的,那么在另一种语言中它要么是逆变的要么是不合理的。
我认为 Scala 在这方面非常接近理想的语言。您引用了一个看起来很像 Scala 的示例,因此您很可能熟悉该语言。我想知道为什么你认为它的类型系统只在某些情况下才能很好地工作。其他情况是什么?
每个有抱负的语言设计师都应该阅读的一本理论著作是 Luca Cardelli 的“对象理论”。
关于language-agnostic - 是否可以统一继承和参数多态的概念?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6731855/