覆盖抽象类

时间:2015-10-06 05:40:20

标签: java generics override

我无法编译一个需要覆盖抽象类超类型方法的方法,该方法使用泛型作为其中一个参数。编译器抱怨扩展类'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()的参数上的相同“签名”无法编译。救命?谢谢!

2 个答案:

答案 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>

对于重写,子类应该在方法中具有与其父类相同的类型参数(在使用泛型时在类型擦除之前)。