Java数组协变是否违反了Liskov替换原则?

5

我正在阅读有关Java中数组协变性不好的原因(为什么数组是协变的,而泛型是不变的?)。如果DogAnimal的子类型,则Dog[]Animal[]的子类型。这是一个问题,因为可以做出以下事情:

Animal[] animals = new Dog[1];
animals[0] = new Cat();

这与泛型不同,泛型被实现得“正确”。 List<Dog> 不是 List<Animal> 的子类型。
我试图理解为什么这是不好的,并刚刚了解了 LSP。它是否以任何方式违反了 LSP?似乎没有明显的违规行为。
1个回答

7

它是否以任何方式违反了 LSP(里氏替换原则)?

是的。

似乎没有明显的违规行为。

您提供的示例存在违反行为。以下代码可以正常工作:

Animal[] animals = new Animal[1];
animals[0] = new Cat();

但如果现在用其子类型 Dog[] 替换 Animal[],那么代码就不再工作(也就是说,在以前没有引起异常的情况下,现在会引发异常)。因此,类型 Dog[] 不能被用在可以使用其超类型 Animal[] 的任何地方,这违反了LSP原则。
用LSP的措辞来说,如果我们考虑属性“new Cat() 可以分配为元素”,则类型 Animal[] 满足该属性,但其子类型 Dog[] 不满足。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接