Contravariance 为什么这些逆变参数类型被认为是安全的?
我刚刚在编程语言课上学到,“逆变参数类型实际上是安全的,但它们没有被发现是有用的,因此在实际语言中不受支持。”即使它们不受支持,我还是不明白为什么我们给出的这个例子在理论上仍然是“安全的”: 据我所知,当做了一些可能导致特异性丧失的事情时,子类型的问题就会出现。那如果我这么做呢Contravariance 为什么这些逆变参数类型被认为是安全的?,contravariance,Contravariance,我刚刚在编程语言课上学到,“逆变参数类型实际上是安全的,但它们没有被发现是有用的,因此在实际语言中不受支持。”即使它们不受支持,我还是不明白为什么我们给出的这个例子在理论上仍然是“安全的”: 据我所知,当做了一些可能导致特异性丧失的事情时,子类型的问题就会出现。那如果我这么做呢 Panda p = new Panda(); Animal a = new Animal ... p.compare(a); 当我看到这一点时,熊猫似乎可以(而且可能确实)拥有一些普通动物不知道的额外领域。因此,即
Panda p = new Panda();
Animal a = new Animal
...
p.compare(a);
当我看到这一点时,熊猫似乎可以(而且可能确实)拥有一些普通动物不知道的额外领域。因此,即使它们所有的动物特定数据成员都是相同的,熊猫也可能有其他不同的东西。把它和普通的动物相比怎么会好呢?它会只考虑动物的东西而忽略其他吗? 在您的示例中,您没有使用任何类型。你有
Panda
扩展Animal
,这是一个例子,并引出了你所描述的内容。检查链接
为了得到逆变,你需要考虑一些泛型。我将使用.NET类型作为示例。使用C#语法(我将使用它而不是Java),通过在定义中写入,我们指出IComparer
在T
中是逆变的:
public interface IComparer<in T>
{
...
}
现在在C#中,可以合法地说:
IComparer<Panda> myPandaComparer = CreateAnimalComparer();
IComparer myPandaComparer=CreateAnimalComparer();
现在,这是因为相反。请注意,类型IComparer
不是从类型IComparer
派生的(或“扩展”)。相反,Panda
源于Animal
,这导致IComparer
可以相互分配(顺序相反,因此是“反向变异”(而不是“协方差”)
声明比较器
逆变式之所以有意义,是因为如果您有一个比较器可以比较两个任意动物,并返回一个有符号的数字,指示哪个更大,那么同一个比较器还可以接收两个熊猫并比较它们。因为熊猫是动物
那么关系呢
任何熊猫
都是动物
(来自继承)导致关系
任何i比较者
都是i比较者
(相反)
对于具有协方差的示例,相同的关系
任何熊猫
都是动物
导致
任何IEnumerable
都是IEnumerable
通过协方差(IEnumerable
)
static IComparer<Animal> CreateAnimalComparer()
{
// code that returns something here
}
IComparer<Panda> myPandaComparer = CreateAnimalComparer();