Java数组协方差是否违反Liskov替换原则?

时间:2017-03-06 22:41:18

标签: generics covariance language-design solid-principles liskov-substitution-principle

我正在阅读为什么Java中的数组协方差很差(Why are arrays covariant but generics are invariant?)。如果DogAnimal的子类型,则Dog[]Animal[]的子类型。这是一个问题,因为这样的事情可以做到:

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

这与正确实施的“仿制药”不同。 List<Dog>不是List<Animal>

的子类型

我试图理解它为什么不好的本质,并且刚刚阅读了LSP。它是否以任何方式违反了LSP?似乎没有明显的违规行为。

1 个答案:

答案 0 :(得分:4)

  

它是否以任何方式违反了LSP?

  

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

您自己的示例是违规行为。以下代码工作正常:

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

但是如果现在将Animal[]替换为其子类型Dog[],代码将不再有效(也就是说,它在以前没有引起异常)。因此,Dog[]类型不能用于可以使用其超类型Animal[]且违反LSP的任何地方。

将其放在LSP的措辞中:如果我们认为属性&#34; new Cat()可以被指定为元素&#34;,类型Animal[]将满足此属性,但它的子类型Dog[]没有。