簡體   English   中英

抽象類中具有通用參數的覆蓋方法

[英]Overriding Method with Generic Parameters from Abstract Class

我無法編譯需要從抽象類超類型重寫方法的方法,該抽象類超類型對參數之一使用泛型。 編譯器抱怨擴展類的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()使用抽象類的類型:

public <M extends AbsClass<Interf>> void setRef(Ref<M> newRef)

但是我想將newRef參數的類型限制為Ref<ChildClass>或子類型,因此這不是完美的。 我如何才能讓擴展類僅允許setClass()方法的newRef參數使用ChildClass或其子類型? 我感到困惑的部分原因是ChildClass的getRef()返回值可以很好地處理通用類型,而setRef()參數上的相同“簽名”無法編譯。 救命? 謝謝!

setRef的問題在於您可以通過AbsClass<? extends Interf>類型的變量訪問ChildClass的實例AbsClass<? extends Interf> AbsClass<? extends Interf> ,因此setRef的參數類型看起來像<M extends AbsClass<? extends Interf>> <M extends AbsClass<? extends Interf>><M extends AbsClass<Q>>可以是任何M但也不匹配<M extends AbsClass<Q>>因為在您的情況下Q已定義為InterfImpl

您可以將ChildClass更改為此:

public <M extends AbsClass<InterfImpl>> void setRef(Ref<M> newRef)

但這仍然允許任何M ,您不能只使用Ref<ChildClass>因為我在上面說過,即如果您使用AbsClass<InterfImpl>類型甚至AbsClass<? extends InterfImpl>類型的變量,編譯器將不了解Ref<ChildClass> AbsClass<? extends InterfImpl> AbsClass<? extends InterfImpl>

僅允許使用ChildClass參數的一種方法是也使用泛型類型的ChildClass ,例如:

public abstract class AbsClass<Q extends Interf, M extends AbsClass<Q, M>> {
  public abstract Ref<M> getRef();
  public abstract void setRef(Ref<M> newRef);
}

public class ChildClass extends AbsClass<InterfImpl, ChildClass> {

  public Ref<ChildClass> getRef() { return null; }

  public void setRef(Ref<ChildClass> newRef) { }
}

您收到錯誤,因為在AbsClass.setRef() ,您的參數類型為Ref<? extends AbsClass<Q>> Ref<? extends AbsClass<Q>>

但是在您的ChildClass.setRef() ,參數的類型為Ref<? extends ChildClass> Ref<? extends ChildClass>

為了進行覆蓋,子類在方法中應具有與其父類相同的類型化參數(在使用泛型時在類型擦除之前)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM