【问题标题】:Subclasses of generic types in JavaJava中泛型类型的子类
【发布时间】:2013-05-02 20:23:47
【问题描述】:
例如,当我有一个接口Drivable 和一个实现该接口的类Car 时。如果我创建一个泛型类型Garage<T extends Drivable> 的类,是否可以创建一个新的Garage<Car> 或者继承不适用于泛型类型,应该是Garage<Drivable>?
【问题讨论】:
标签:
java
generics
inheritance
types
interface
【解决方案1】:
答案取决于你想把什么类型的Drivable放入Garage' 如果你希望能够把任何类型的Drivable放入Garage,那么将其声明为Garage<Drivable> .如果您只希望该特定实例包含Car 实例,那么将其声明为Garage<Car> 是完全可以接受的。
【解决方案2】:
当你创建一个类Garage<T extends Drivable>时,这意味着Garage可以接受实现Drivable的类或者Drivable的子接口或者实现Drivable子接口的类。基本上,它检查类 IS-A Drivable。在这种情况下,由于Car IS-A Drivable,您可以拥有Garage<Car>。
【解决方案3】:
是的,您可以实例化Garage<Car> 类型的对象,因为Car 实现了所需的Drivable 接口,因此符合泛型类型约束。
【解决方案4】:
是的,可以创建Garage<Car>。
但是,Garage<Car> 不是Garage<Drivable> 的子类。要知道为什么,想象一下如果是 - 那么下面的代码会编译:
public void putBikeAway(Motorbike bike, Garage<Driveable> garage) {
garage.parkVehicle(bike);
}
Garage<Car> garage = new Garage<Car>();
Garage<Drivable> dgarage = garage; // doesn't compile in reality
Motorbike b = new Motorbike();
putBikeAway(b, dgarage);
// We now have a Motorbike in a Garage<Car>!
// So later on...
Car car = garage.getVehicle(); // throws ClassCastException at runtime
因此,Garage<Car>不是Garage<Drivable> 的实例(因为如果是,您可以向其添加Motorbike,并且泛型类型安全被完全颠覆) .相反,在我的示例中,将在第 6 行引发编译时错误。