Java 数组协变是否违反里氏代换原则?
Does Java array covariance violate Liskov Substitution Principle?
我正在阅读为什么 Java 中的数组协方差不好 (Why are arrays covariant but generics are invariant?)。如果 Dog
是 Animal
的子类型,那么 Dog[]
是 Animal[]
的子类型。这是一个问题,因为可以这样做:
Animal[] animals = new Dog[1];
animals[0] = new Cat();
这与实现的泛型不同 'correctly'。 List<Dog>
不是 List<Animal>
的子类型
我试图理解它为什么不好的本质,并且刚刚阅读了有关 LSP 的内容。它是否以任何方式违反了 LSP?似乎没有明显的违规行为。
Did it violate the LSP in any way?
是的。
There doesn't seem to be a clear violation.
你自己的例子是违规的。以下代码工作正常:
Animal[] animals = new Animal[1];
animals[0] = new Cat();
但是,如果现在将 Animal[]
替换为它的子类型 Dog[]
,代码将不再有效(也就是说,它会导致异常,而以前不会)。所以类型 Dog[]
不能在任何可以使用它的超类型 Animal[]
并且违反 LSP 的地方使用。
将其放入 LSP 的措辞中:如果我们考虑 属性“new Cat()
可以作为元素分配”,类型 Animal[]
满足此 属性 ,但它的子类型 Dog[]
没有。
我正在阅读为什么 Java 中的数组协方差不好 (Why are arrays covariant but generics are invariant?)。如果 Dog
是 Animal
的子类型,那么 Dog[]
是 Animal[]
的子类型。这是一个问题,因为可以这样做:
Animal[] animals = new Dog[1];
animals[0] = new Cat();
这与实现的泛型不同 'correctly'。 List<Dog>
不是 List<Animal>
我试图理解它为什么不好的本质,并且刚刚阅读了有关 LSP 的内容。它是否以任何方式违反了 LSP?似乎没有明显的违规行为。
Did it violate the LSP in any way?
是的。
There doesn't seem to be a clear violation.
你自己的例子是违规的。以下代码工作正常:
Animal[] animals = new Animal[1];
animals[0] = new Cat();
但是,如果现在将 Animal[]
替换为它的子类型 Dog[]
,代码将不再有效(也就是说,它会导致异常,而以前不会)。所以类型 Dog[]
不能在任何可以使用它的超类型 Animal[]
并且违反 LSP 的地方使用。
将其放入 LSP 的措辞中:如果我们考虑 属性“new Cat()
可以作为元素分配”,类型 Animal[]
满足此 属性 ,但它的子类型 Dog[]
没有。