java extends T>

16996 ワード

extends T>とsuper T>はJava汎用における「ワイルドカード」と「境界(Bounds)」の概念である
extends T>とは、「上界ワイルドカード1.なぜワイルドカードまたは境界の概念を使用して汎用を使用するのか、例えばFruitクラスとその派生クラスAppleクラスがある.
public class Fruit {
    private String name;

    public Fruit(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class Apple extends Fruit {

    private boolean isRed;

    public Apple(boolean isRed,String name) {
        super(name);
        this.isRed = isRed;
    }

    public boolean isRed() {
        return isRed;
    }

    public void setRed(boolean red) {
        isRed = red;
    }
}

それから最も簡単な容器があります:Plate類.皿の中に1つのものを置くことができます.私たちはこのものに対して最も簡単な「置く」と「取る」動作をすることができます:set()とget()方法.
public class Plate<T> {
    private T item;

    public Plate(T t) {
        this.item = t;
    }

    public T get() {
        return item;
    }

    public void set(T item) {
        this.item = item;
    }


    public static void main(String[] args) {
        Plate<Apple> pa=new Plate<Apple>(new Apple(true,"  "));
        Plate<Fruit> pf = new Plate<Apple>(new Apple(true,"  "));
    }
}

1行目のコードのコンパイルに成功し、2行目のコードは「互換性のないタイプで、Plateが必要で、Plateが提供されている」と直接報告されています.ここは変な感じがします.りんごを入れる皿は果物を入れる皿ではありません.new Plate(new Apple(true,「アップル」)を;の引用はPlateに付与できません.容器に入っているものの間に継承関係があっても、容器の間には継承関係がありません.だから、Plateを割り当てることはできません.
したがって、汎用型をより快適に使用するために、extends T>を使用して汎用型間に関係を持たせます.以下のコードは、参照が受け入れられることを示しています.果物を入れた皿やりんごを入れたり、他の果物の子類を入れた皿の参照
Plate<? extends Fruit> pf = new Plate<Apple>(new Apple(true,"  "));

副作用:中に入れないで、外に取るしかありません
まず、外に取り出して取得したオブジェクトのタイプを見てみましょう.
public static void main(String[] args) {
        Plate<? extends Fruit> pf = new Plate<Apple>(new Apple(true,"  "));
        Fruit f = pf.get();
        Apple a = pf.get();//       
        System.out.println(f.getName());
    }

以上のコードでpf内のオブジェクトをFruitオブジェクトに取り出しても問題はありませんが、付与がAppleタイムズで間違っていて、タイプが一致していないと言って、FruitタイプはAppleタイプに付与できません.ただし、格納がAppleタイプであることが明確にわかっているので、強制タイプ変換を行っても問題はありません
 public static void main(String[] args) {
        Plate<? extends Fruit> pf = new Plate<Apple>(new Apple(true,"  "));
        Fruit f = pf.get();
        Apple a = (Apple) pf.get();
        System.out.println(f.getName());
        System.out.println(a.isRed()+a.getName());
    }

これ以上中に入れないでください.
public static void main(String[] args) {
        Plate<? extends Fruit> pf = new Plate<Apple>(new Apple(true,"  "));
        pf.set(new Apple(true,"  "));
        pf.set(new Fruit("  "));
    }

以上のコードは、皿に果物を入れてもりんごを入れても間違っています.なぜなら、コンパイラは容器内がFruitかその派生類であることしか知らないからですが、具体的にはどんなタイプなのか分かりません.Fruitかもしれません.Appleかもしれません.Bananaかもしれません.だからコンパイラは容器内に何が入っているのか分かりませんが、プレースホルダ:xxxと表示され、FruitかFruitを持っていることを示しています.そして、AppleやFriutコンパイラに挿入しようとしても、挿入したもののタイプが、これがすでに入っているもの(xxx)と一致するかどうかはわかりません.容器は、自分が何を預けることができるか分からない容器になっているので、許されません.