子类集不匹配超类集

Ale*_*ell 1 java inheritance set

假设我有两个类:

public class Bike {}
public class MountainBike extends Bike {}
Run Code Online (Sandbox Code Playgroud)

当我按如下方式创建方法时,它不会抛出任何错误:

Bike mountainBike = new MountainBike();
// method signature is addBike(Bike bike); 
addBike(mountainBike);
Run Code Online (Sandbox Code Playgroud)

但如果我尝试以下方法:

Set<MountainBike> bikes = new HashSet<MountainBike>();
// method signature is addBikes(Set<Bike> bikes);
addBikes(bikes);
Run Code Online (Sandbox Code Playgroud)

我收到错误的方法签名匹配错误.如何创建包含子类的Set?

Stu*_*etz 5

你要这个:

addBikes(Set<? extends Bike> bikes)
Run Code Online (Sandbox Code Playgroud)

此外,作为@Blacklight指出,Set本身是一个接口,所以您不能直接对其进行实例化(您需要实例其具体的实现方式之一,例如HashSet,LinkedHashSetTreeSet).

这里的关键点是它Set<MountainBike>不是一个子类型Set<Bike>- 特别是,您可以将除自行车之外的自行车添加到一组自行车,而不是一组山地自行车.因此,Java会阻止您将类型安全性的原因传递Set<MountainBike>给方法Set<Bike>,因为否则您将能够在方法中的集合中添加非山地自行车而不会被编译器标记(它会而是导致运行时错误).

作为一个额外的观察,请注意一组不可改变的山地自行车将是一组不可改变的自行车 - 这是导致问题的可变性.这与可以用其他语言(特别是C#)表达的类型参数的协方差和逆变的概念联系在一起.