泛型< ? extends > <? super> 理解

public class Test {
   public  static  void  main(String [] args){
    Plate<? extends Fruit> p = new Plate<Apple>(new Apple());
       Food food = p.get();
       Fruit fruit = p.get();

     //ERROR
//       p.set(new Fruit());
//       p.set(new Orange());
//       p.set(new Apple());
    //error
    //  Apple apple = p.get();
Plate<? super Fruit> p1 = new Plate<Fruit>(new Fruit());
p1.set(new Apple());
p1.set(new Orange());
p1.set(new Fruit());
Object object = p1.get();


   }
}
class Plate<T>{
    private T item;
    public Plate(T t){
        item = t;
    }
    public T get() {
        return item;
    }
    public void set(T item) {
        this.item = item;
    }
}

//父类
class Food {
    void eatFood(){
        System.out.println("eatFood");
    }
}
//子类1
class Fruit extends Food{
    void eatFruit(){
        System.out.println("eatFruit");
    }
}
class Meat extends Food{
    void eatMeat(){
        System.out.println("eatMeat");
    }
}
//子类2
class Apple extends Fruit{
    void eatApple(){
        System.out.println("eatApple");
    }
}
class Orange extends Fruit{
    void eatOrange(){
        System.out.println("eatOrange");
    }
}
class Pork extends Meat{
    void eatPork(){
        System.out.println("eatPork");
    }
}

class Beaf extends Meat{
    void eatBeaf(){
        System.out.println("eatBeaf");
    }
}

<? extends Fruit> 相当于是什么意思? 就是 ? extends Fruit 里面是Fruit类或者他的子类但是具体什么类型不知道
所以可能是Fruit 可能是Apple可能是Orange 这里面相当于标记了一个占位符:CAP#1 但是不能插入他的子类了,
<?> 不写默认是<? extends Object>
所以取得时候只能取父类的类型 向下转型嘛 父类new子类对象可以
所以这种写法适合去取 因为set会失效
Plate相当于一个容器 <?>与<T>不同的是 <T>是可以已知的
<? extends Fruit> 规定了他的上界限是 Fruit 但是下面的类型不能确定
所以我不能存,因为如果我的下面的类型细度比较大,存进去的时候就会有信息丢失 ,但是我取的时候可以取他父类的类型这样就没有丢失
相反的可以这样 <? super Fruit> 这里面存的是Fruit的父类 那么就不能插入Fruit的父类了 但是向下转型只要是子类都是可以
放进去,粒度比这个小都可以放进去
取得时候只能取到<? super Fruit> 相当与是没有上限的父类 那就是Object类

posted @ 2018-07-12 15:21  致良知的萌新  阅读(5716)  评论(0编辑  收藏  举报