2015-04-22 22 views
2

Java不允許Collection<Car>作爲Collection<Vehicle>的子類型。這是因爲Collection<Car>不能用於代替每個Collection<Vehicle>,因爲Collection<Vehicle>可能包含車輛的其他子類型的元素,如摩托車,因此違反了Liskov替代原則?收藏品子類 - Liskov替換原理

+0

這與使用泛型和與之相關的協方差響應中的不變性挑戰更相關 – alainlompo

回答

0

不完全。反過來:

那個Collection<Car>只包含Car s很好,即使Collection<Vehicle>可能包含其他類型的車輛。你仍然可以給Collection<Car>任何人誰可以處理Collection<Vehicle>元素。

Collection<Car>不能代替Collection<Vehicle>的使用,因爲你可以把一個BicycleCollection<Vehicle>(而不是在一個Collection<Car>)。因此,您不能將Collection<Car>交給想要收集車輛的人。

1

一般而言,Collection由於存在「可選操作」而違反了Liskov替換原則,即突變方法可能無法用於特定實現。

關於類型安全,但是,它的工作原理這樣:

假設CarVehicle一個亞型,一個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>,是一個方差的問題(協方差是這種情況)。

Liskov替代原則超越了類型一致性的方式,它不僅要求提供更多,要求更少,而且要保留超類型的合約,see Wikipedia

0

請注意,Collection<Car>不變的在組件類型Car上。因此,如果您想使用可能是汽車,自行車,火車等的車輛集合,則應該採取協同集合Collection<? extends Vehicle>

當然,如果你有應某處停放生產的汽車生產一個方法CarFactory,一個逆變produce(Collection<? super Car>)方法將是最有用的實現。