2

维基百科定义covariance

从较宽的(动物)转换为较窄的(猫)。

但是在类似的语言中Java,返回类型协方差被定义为将子类型分配给超类型,例如:

public Animal getAnimal(){
   return new Cat();
}

在这里,我们将子类型分配给超类型,但根据Wikipedia定义,协方差将超类型分配给子类型。我怎样才能调和两者?

4

4 回答 4

2

您对协变返回类型的含义有误解。

它仅在您覆盖方法时才相关,它不涉及返回语句中使用的类型或调用者对方法的期望。协变返回类型意味着您可以覆盖子类型中的方法并在覆盖期间更改返回类型(使其返回类型比超类型中的方法更窄)。

例子:

public class SuperType {
  public Animal getAnimal() { ... }
}

public class SubType extends SuperType {
  public Cat getAnimal() { ... }
}

这里与维基百科的定义相匹配。

Java 语言规范在第8.4.8.3 节中确认了这一点(参见示例 8.4.8.3-1)。

请注意,对于方法参数,Java 需要逆变类型。如果采用ingetAnimal类型的参数,则该类不能将此参数缩小到,但可以将其扩大到 (eg) 。AnimalSuperTypeSubTypeCatObject

于 2012-11-13T08:27:24.313 回答
1

通用术语“协变”意味着可以沿轴变化的两个实体,并且它指出这些实体是相关的,因此当一个生成zig时,另一个也生成zig。相反,“逆变”意味着当一个人做zig时,另一个人做zag

具体来说,在类型理论中,如果当我们缩小一种类型时,另一种类型也被缩小,则两种类型是协变的。

将此应用于 Java 返回类型,当我们从一个类到其子类时,方法的返回类型可以以相同的方式进行:从类到子类。

将此与对方法参数有意义的情况进行对比:从类到子类,参数类型可能从类到超类。Java 中不存在此功能,但如果存在,这将是它的工作方式。

于 2012-11-13T09:03:01.580 回答
0

正如您所说,维基百科协方差的定义与 Java 函数所做的相同。该函数返回一个动物,但在这种情况下,它将其范围缩小为一只猫(因此变化更多)。

您可能在“根据维基百科的定义,协方差将超类型分配给子类型”时出错了。因为这与从更宽(动物)转换为更窄(猫)不同,但恰恰相反。

//This is covariance, as you go from wider, to narrower
Animal someAnimal = new Animal();
someAnimal = getAnimal(); //now someAnimal is a cat, as by your code example.
于 2012-11-13T08:09:27.053 回答
0

您也许应该尝试通过以下方式查看它:

方法是说:“我给你一只动物”,如果它后来给你一只猫,它就没有撒谎。它从较宽的类型变为较窄的类型。

于 2012-11-13T08:36:29.393 回答