2

Java does not permit Collection<Car> as a subtype of Collection<Vehicle>. Is this because Collection<Car> cannot be used in place of every Collection<Vehicle> as the Collection<Vehicle> could contain elements which are other subtypes of Vehicle such as Motorbike, therefore it violates Liskov substitution principle?

4

4 回答 4

1

通常,Collection由于“可选操作”的存在,s 违反了 Liskov 替换原则,即变异方法可能无法用于特定的实现。

然而,关于类型安全,它是这样工作的:

假设它Car是 的子类型Vehicle,aCollection<Car>是允许类似操作的类型

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

Collection<Vehicle>没有。另一方面,Collection<Vehicle>是一种允许类似操作的类型

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

Collection<Car>没有。因此,这些Collection类型都不是另一个的子类型。

于 2015-04-22T10:53:57.963 回答
0

Collection<T>是类型构造函数,因此Collection<Car>是类型并且Collection<Vehicle>是另一种类型。

现在的问题是,如果 aCollection<Car>可以在Collection<Vehicle>需要 a 的地方使用,那就是方差问题(这种情况是协方差)。

Liskov 替换原则以某种方式超越了类型一致性,它不仅要求提供更多,要求更少,而且还保留了超类型的合同,请参阅 Wikipedia

于 2015-04-22T11:04:58.503 回答
0

请注意, a在组件类型上Collection<Car>不变Car的。因此,如果您想使用可能是汽车、自行车、火车等的车辆集合,您应该使用协变集合Collection<? extends Vehicle>

当然,如果你有CarFactory一个生产方法,应该将生产的汽车停在某个地方,那么逆变 produce(Collection<? super Car>)方法将是最有用的实现。

于 2015-04-22T11:19:32.210 回答
0

不完全是。另一种方式:

aCollection<Car>只包含Cars 很好,即使 aCollection<Vehicle>可能包含其他类型的车辆。您仍然可以将 a 提供Collection<Car>给任何可以处理 a 中的元素的人Collection<Vehicle>

Collection<Car>不能用于代替 a Collection<Vehicle>,因为您可以将 aBicycle放入 a Collection<Vehicle>(但不能放入 a Collection<Car>)。所以你不能把它Collection<Car>交给想要收集车辆的人。

于 2015-04-22T10:50:14.460 回答