Нарушает ли ковариация массива Java принцип подстановки Лисков?

Я читал, почему ковариантность массивов в Java плохая (Почему массивы ковариантны, но дженерики инвариантны?). Если Dog является подтипом Animal, то Dog[] является подтипом Animal[]. Это проблема, потому что такие вещи можно сделать:

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

Это отличается от дженериков, которые были реализованы «правильно». List<Dog> не является подтипом List<Animal>

Я пытался понять суть того, почему это плохо, и только что прочитал о LSP. Это как-то нарушало LSP? Явного нарушения вроде бы нет.




Ответы (1)


Это как-то нарушало LSP?

да.

Явного нарушения вроде бы нет.

Ваш собственный пример является нарушением. Следующий код работает нормально:

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

Но если теперь заменить Animal[] его подтипом Dog[], код перестанет работать (то есть вызовет исключение, которого раньше не было). Таким образом, тип Dog[] нельзя использовать там, где можно использовать его супертип Animal[], и это нарушает LSP.

Чтобы выразить это в формулировке LSP: если мы рассмотрим свойство «new Cat() может быть назначено как элемент», тип Animal[] соответствует этому свойству, а его подтип Dog[] — нет.

person sepp2k    schedule 06.03.2017