7

これは私の最初の SO の質問です。読者と私自身の両方にとって十分に役立つことを願っています! 私は過去 2 日間、これを使って世界中をググったり、ダックしたりしてきました。

具体的なモデルとストレージ クラスが派生する抽象モデルとストレージ クラスがあります。

abstract class Food {}

abstract class FoodStorage<T extends Food> {
    abstract void setFood(T food);
}

class Apple extends Food {}

class Basket extends FoodStorage<Apple> {
    @Override
    void setFood(Apple apple) {
        // Save that apple to the basket
    }
}

問題ない。今、私はインスタンスでsave()直接a を呼び出し、それを(バスケットを気にすることなく)Appleそのインスタンスに永続化し、それを抽象クラスに実装できるようにしたいと考えています。Basket私が見つけた最高のものはこれです:

abstract class Food<T extends Food<T,S>,
        S extends FoodStorage<T,S>> {

    abstract S getStorage();

    void save() {
        getStorage().setFood((T)this); // <---- Unchecked cast warning
    }

}

abstract class FoodStorage<T extends Food<T,S>, S extends FoodStorage<T,S>> {
    abstract void setFood(T food);
}

class Apple extends Food<Apple,Basket> {
    Basket basket = new Basket(); // or Basket.getInstance();

    @Override
    Basket getStorage() {
        return basket;
    }
}

class Basket extends FoodStorage<Apple,Basket> {
    @Override
    void setFood(Apple apple) {
        // Save that apple to the basket
    }
}

これは機能しますが、IntelliJ は のチェックされていないキャストに関する警告を表示しsave()ます。確かに、私は からFood<T,S>にキャストしていTます。

質問: これをタイプセーフな方法で実装するにはどうすればよいapple.save()ですか?

クライアントコードにワイルドカードを表示したくないので、に変更abstract void setFood(T food);することabstract <Z extends Food<T,S>> void setFood(Z food);は解決策ではありません。(もちろん私SupressWarnings("unchecked")も避けています)。

クラス階層を使用するときに未チェックの割り当て警告を回避するにはどうすればよいですか? 、Generics cast issue、およびget-put 原則、しかし、私はまだそれについて頭を悩ませることができません。

前もって感謝します!

4

1 に答える 1