在覆盖期间将具体对象返回给具有通用Map参数的通用方法

时间:2018-10-23 10:33:48

标签: java oop generics

我有一个带有通用Map参数的通用方法。我想覆盖它并使用具体的子类型,但是如果不进行强制转换,我将无法返回我的子类型

public interface GarrageSimple {
    <T extends Car> T getCar(Map<String, T> c);
}

实现如下,其错误如下:类型不兼容。必需: T 找到:宝马

public class GarrageSimpleImpl implements GarrageSimple {

    @Override
    public <T extends Car> T getCar(Map<String, T> c) {
        return new Bmw();
    }
}

实际上,Bmw是Car的子类,表示T的类型。当我像*一样将其强制转换为return(T)new Bmw(); *时,它会警告未选中将Bmw强制转换为T

我知道这是因为我冒着在方法签名是泛型的情况下返回具体子类的风险,但是如何更改我的方法使其具体而又不破坏覆盖签名? 如果可以的话,它应该可以正常工作。

PS:我不想使我的类通用,我只需要更改我的方法签名以在实现期间使其具体化即可。

谢谢

2 个答案:

答案 0 :(得分:4)

否,这无效。如果有人使用GarrageSimpleImpl引用使用另一个扩展Car的类来调用它,将会发生什么情况?泛型全部与编译时安全有关,这就是为什么会出现此错误的原因。

但是您可以这样做,

public interface GarrageSimple<T extends Car> {
     T getCar(Map<String, T> c);
}


public class GarrageSimpleImpl implements GarrageSimple<Bmw> {
    @Override
    public Bmw getCar(Map<String, Bmw> c) {
        return new Bmw();
    }
}

答案 1 :(得分:0)

不能。通用方法(声明其自己的类型参数的方法)意味着无论类型参数(此处为T)如何,方法都必须起作用。该方法无法选择要使用的T。调用方可以使用T范围内的任何内容T来调用您的方法,并且您的方法必须能够正确地处理T所无法选择的任何内容。

在超类中重写方法的子类意味着该子类方法必须是该重写方法的有效替代品,这意味着它必须在可以调用该重写方法的所有情况下都可以工作。由于该重写方法是通用的,并且适用于任何T,覆盖它的子类方法也必须适用于任何T。您的方法不适用于任何T,但不适用于不是T的任何Bmw