我无法编译一个需要覆盖抽象类超类型方法的方法,该方法使用泛型作为其中一个参数。编译器抱怨扩展类'setRef()方法不会覆盖超类型中的方法。
父抽象类:
public abstract class AbsClass<Q extends Interf> {
public abstract Ref<? extends AbsClass<Q>> getRef();
public abstract <M extends AbsClass<Q>> void setRef(Ref<M> newRef);
}
参考是:
public interface Ref<M extends AbsClass<? extends Interf>> { }
和Interf是:
public interface Interf { }
扩展子类(setRef()不编译):
public class ChildClass extends AbsClass<InterfImpl> {
@Override
public Ref<ChildClass> getRef() {
return null;
}
@Override
public <M extends ChildClass> void setRef(Ref<M> newRef) {
return null;
}
}
我也尝试过使用通配符,并收到同样的错误。对于通配符,抽象类'setRef()是:
public abstract void setRef(Ref<? extends AbsClass<Q>> newRef);
和扩展类'setRef()是:
public void setRef(Ref<ChildClass> newRef)
甚至:
public void setRef(Ref<? extends ChildClass> newRef)
我可以编译它的唯一方法是扩展类'setRef()使用抽象类'type:
public <M extends AbsClass<Interf>> void setRef(Ref<M> newRef)
但是我想将newRef参数的输入限制为Ref<ChildClass>
或子类型,所以这并不完美。如何让我的扩展类只允许ChildClass或其子类型用于setRef()方法的newRef参数?令我困惑的部分原因是ChildClass的'getRef()返回值处理通用类型很好,并且setRef()的参数上的相同“签名”无法编译。救命?谢谢!
答案 0 :(得分:1)
setRef
的问题是您可以通过ChildClass
类型的变量访问AbsClass<? extends Interf>
的实例,因此setRef
的参数类型看起来像{{ 1}}也可以是任何<M extends AbsClass<? extends Interf>>
,但也不匹配M
,因为<M extends AbsClass<Q>>
已被定义为Q
。
您可以将InterfImpl
更改为:
ChildClass
但这仍然允许任何public <M extends AbsClass<InterfImpl>> void setRef(Ref<M> newRef)
,你不能只使用M
,因为我上面所说的,即编译器不会知道Ref<ChildClass>
如果您使用了Ref<ChildClass>
或AbsClass<InterfImpl>
类型的变量。
仅允许AbsClass<? extends InterfImpl>
参数的一种方法是在通用类型中使用ChildClass
,例如像这样:
ChildClass
答案 1 :(得分:0)
您收到错误,因为在AbsClass.setRef()
中,您的参数类型为Ref<? extends AbsClass<Q>>
但在您的ChildClass.setRef()
中,参数的类型为Ref<? extends ChildClass>
。
对于重写,子类应该在方法中具有与其父类相同的类型参数(在使用泛型时在类型擦除之前)。