这将是协变返回类型的示例:
class Food {}
class Fruit : Food {}
class FoodEater
{
public virtual Food GetFavouriteFood() { ... }
}
class FruitEater : FoodEater
{
public override Fruit GetFavouriteFood() { ... }
}
在支持返回类型协变的语言中,这是合法的。那就是返回食物的方法可以被返回水果的方法覆盖,因为水果是食物的一种。之所以称为“协方差”,是因为“方差”在同一个方向:
A Fruit may be used as a Food, therefore:
A Fruit-returning-method may be used as a Food-returning-method
看看方差是如何在同一个方向?
与参数类型逆变对比:
class Food {}
class Fruit : Food {}
class Apple : Fruit {}
class Orange : Fruit {}
class Cake : Food {}
class FruitComparer
{
public virtual bool Compare(Fruit f1, Fruit f2) { ... }
}
class FoodComparer : FruitComparer
{
public override bool Compare(Food f1, Food f2) { ... }
}
FruitComparer 可以比较苹果和橙子。 FoodComparer 还可以将苹果与橙子进行比较,但可以进行更多的比较——它可以将苹果与蛋糕进行比较,或者将蛋糕与橙子进行比较,或者其他任何东西。
在支持参数类型逆变的语言中,这是合法的。看看现在方差方向如何反转:
A Fruit may be used as a Food, therefore
A Food-taking-method may be used as a Fruit-taking-method
现在关系已经倒退,所以它是逆变的。
C# 不支持两种方法变体用于虚拟重载。虚拟方法覆盖必须完全匹配。但是,C# 确实支持方法组委托转换和通用委托类型转换的两种方法变化。