共変戻りタイプのメソッドをオーバーライドできますが、デフォルトのメソッドを共変戻りタイプでオーバーライドすることはできますか?次の例では、デフォルトのメソッドを書き直すことなくgetFirstLegをオーバーライドしたいと考えていますが、Javaではこれを許可していません。また、多くのパラメータがあり、Animalが多くの場所で使用されているため、Animalを汎用インターフェイスにしたくないです。デフォルトメソッドの共変戻りタイプ
更新:次のコードはコンパイルされますが、新しい問題はDuckがもはやAnimalではないということです。
interface Leg {
}
interface AnimalGeneric<T extends Leg> {
List<? extends T> getLegs();
default T getFirstLeg() {
return getLegs().get(0);
}
}
abstract class AnimalImpl<T extends Leg> implements AnimalGeneric<T> {
private List<T> legs;
@Override
public List<T> getLegs() {
return legs;
}
}
interface Animal extends AnimalGeneric<Leg> {
//empty
}
interface BirdLeg extends Leg {
}
interface BirdGeneric<T extends BirdLeg> extends AnimalGeneric<T> {
}
class BirdImpl<T extends BirdLeg> extends AnimalImpl<T> implements BirdGeneric<T> {
}
interface Bird extends BirdGeneric<BirdLeg> {
//empty
}
interface DuckLeg extends BirdLeg {
}
class DuckImpl extends BirdImpl<DuckLeg> implements Duck {
}
interface Duck extends BirdGeneric<DuckLeg> {
}
は私の記事で最後の文を参照してください。私はAnimal(または他の広く使われているインターフェース)を一般化することに懸念を抱いています。なぜなら、パラメータを変更したい場合は、多くの場所を変更する必要があるからです。 – Fan
リストはリスト<ですか? Leg>を拡張し、List <? DuckLeg> List <?脚を伸ばす>? –
Fan
Javaのジェネリックは不変であるため、問題を正確に解決するには、 'Animal'ジェネリックを使ってください。また、 'List <? extends DuckLeg> '' List <? 'にすることはできません。ワイルドカードは特定の未知の型を表すため、Leg> 'を拡張します。 'List <? extends DuckLeg>は 'List
'を表すことができ、 'List <? extends Leg>は 'List 'を表すことができます。不一致の可能性があるため、コンパイラはワイルドカードで共変ジェネリックスを禁止する必要があります。 –
rgettman