2015-04-22 5 views
2

Ява не разрешает Collection<Car> как подтип Collection<Vehicle>. Это потому, что Collection<Car> не может использоваться вместо каждого Collection<Vehicle>, поскольку Collection<Vehicle> может содержать элементы, которые являются другими подтипами транспортного средства, такие как мотоцикл, поэтому он нарушает принцип замещения Лискова?Подтипы коллекций - Лисков Замена Принцип

+0

Это больше связано с проблемой инвариантности при использовании дженериков и ковариантного ответа, который идет с ним. – alainlompo

ответ

0

Не совсем. В противоположном случае:

Что касается Collection<Car>, то содержит только Car. S в порядке, хотя Collection<Vehicle> может содержать другие типы транспортных средств. Вы все равно можете дать Collection<Car> всем, кто может обрабатывать элементы из Collection<Vehicle>.

Но Collection<Car> не может использоваться вместо Collection<Vehicle>, потому что вы могли бы поставить Bicycle в Collection<Vehicle> (но не в Collection<Car>). Поэтому вы не можете дать Collection<Car> тем, кто хочет собирать автомобили.

1

В целом, Collection нарушает принцип замещения Лискова из-за существования «необязательных операций», то есть методы мутации могут быть непригодными для конкретной реализации.

Что касается безопасности типа, однако, она работает таким образом:

Если предположить, что Car является подтипом Vehicle, Collection<Car> представляет собой тип, который позволяет операцию как

Collection<Car> c=…; 
Car car=c.iterator().next(); 

который Collection<Vehicle> Безразлично» т. С другой стороны, Collection<Vehicle> представляет собой тип, который позволяет операцию, как

Collection<Vehicle> c=…; 
Vehicle v=…; 
c.add(v); 

, который Collection<Car> не делает. Поэтому ни один из этих типов Collection не является подтипом другого.

+0

См. Http://stackoverflow.com/questions/22050848/do-collections-unmodifiablexxx-methods-violate-lsp для обсуждения о том, нарушают ли методы мутации коллекции методы LSP. – jaco0646

0

Collection<T> является конструктором типа, поэтому Collection<Car> является типом и Collection<Vehicle> - это другой тип.

Теперь вопрос, если требуется Collection<Car>, где требуется Collection<Vehicle>, является вопросом дисперсии (сопутствующий случай - это случай).

Принцип замены Лискова превосходит тип соответствия таким образом, что он не только требует большего, требует меньше, но также и того, что договор супертипа сохраняется, see Wikipedia.

0

Отметьте, что Collection<Car> является неизменным над состоянием типа Car. Поэтому, если вы хотите использовать коллекцию транспортных средств, которые могут быть автомобилями, велосипедами, поездами и т. Д., Вы должны взять ковариантCollection<? extends Vehicle>.

Конечно, если у вас есть CarFactory с методом продукции, который должен парковать произведенные машины где-то, контравариантенproduce(Collection<? super Car>) метод будет наиболее полезным выполнением.

Смежные вопросы