I was reading why array covariance in Java is bad (Why are arrays covariant but generics are invariant?). If a Dog
is a subtype of Animal
, then a Dog[]
is a subtype of Animal[]
. This is a problem because things like this can be done:
Animal[] animals = new Dog[1];
animals[0] = new Cat();
This is different from generics which were implemented 'correctly'. A List<Dog>
is not a subtype of List<Animal>
I was trying to understand the essence of why it is bad and had just read about LSP. Did it violate the LSP in any way? There doesn't seem to be a clear violation.
Did it violate the LSP in any way?
Yes.
There doesn't seem to be a clear violation.
Your own example is a violation. The following code works fine:
Animal[] animals = new Animal[1];
animals[0] = new Cat();
But if now replace the Animal[]
with its subtype Dog[]
, the code no longer works (that is, it causes an exception when it didn't previously). So the type Dog[]
can't be used everywhere where its supertype Animal[]
can be used and that violates the LSP.
To put this in the LSP's wording: If we consider the property "new Cat()
can be assigned as an element", the type Animal[]
fulfils this property, but its subtype Dog[]
does not.