Collection<Car>
Java はのサブタイプとして許可しませんCollection<Vehicle>
。これは、 Motorbike などの Vehicle の他のサブタイプである要素を含む可能性があるため、 everyのCollection<Car>
代わりに使用できないため、Liskov 置換原則に違反しているためですか?Collection<Vehicle>
Collection<Vehicle>
4 に答える
一般に、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
タイプはどちらも他方のサブタイプではありません。
Collection<Car>
aはコンポーネント タイプに対して不変であることに注意してくださいCar
。したがって、車、バイク、電車などの車両のコレクションを使用する場合は、共変コレクションを使用する必要がありますCollection<? extends Vehicle>
。
もちろん、CarFactory
生産された車をどこかに駐車する生産メソッドがある場合は、反変 produce(Collection<? super Car>)
メソッドが最も有用な実装になります。
Collection<T>
は型コンストラクターであるためCollection<Car>
、型であり、Collection<Vehicle>
別の型です。
ここCollection<Car>
で、a が必要な場所で a を使用できるかどうかというCollection<Vehicle>
問題は、分散の問題です (共分散がこの場合です)。
Liskov 置換の原則は、より多くを提供する必要があるだけでなく、より少ない必要があるだけでなく、スーパータイプの契約が維持されるという形で、型の適合性を超えています。Wikipedia を参照してください。