泛型的 上下边界约束

package com.rq.util.module.exercise.capture;

/**

 * 频繁读取内容的使用 上界(extends)

 * 频繁插入的,用下界(skuper)

 * @author rq

 *

 */

public class TestCapture2 {

      @SuppressWarnings("unused")

      public static void main(String[] args) {

            Plate<Fruit> fruitPlate = new Plate<Fruit>(new Apple());

            Fruit apple = new Apple(); // 元素之间的转型没有问题

//          Plate<Fruit> applePlate = new Plate<Apple>(new Apple());  // Apple类型的plate, 无法转成 Fruit类型的plate,,容器之前不能转型

            // 不能存、只能取

            Plate<? extends Fruit> applePlate = new Plate<Apple>(new Apple()); // 允许Fruit及其子类的容器创建

            Fruit a1 = applePlate.get(); // 1*** 本质是一个强制转换,?的类型一定是泛型的子类(或等于泛型本身),因此此处是一个向上转型,不用强制转换,类型安全** 但是调用方法只能是父类的,子类未重写的方法全部丢失 **

            Object a2 = applePlate.get();

//          Apple a3 = applePlate.get(); // 编译器只知道容器内饰Fruit或其派生类(子类),具体不知道,可能是Apple、Banana、GreenApple...

//          applePlate.put(new Apple()); // 无论插入什么类型的值,编译器都不知道能不能和泛型匹配,所以都不允许插入  <capture#3-of ? extends Fruit> is not applicable for the arguments (Apple)

//          <?> 表示任意内容,区分 <? extends ??>

            applePlate.put(null);

            Plate<? super Fruit> superFruitPlate1 = new Plate<Fruit>(new Apple()); // Fruit及其基类(父类)的容器创建

            Plate<? super Fruit> superFruitPlate2 = new Plate<Food>(new Apple());

            superFruitPlate1.put(new Fruit());

            superFruitPlate1.put(new Apple());

//          Apple a3 = superFruitPlate1.get();  // 既然元素是Fruit的基类,那么往里存的数据比Fruit小的都可以,但是取值就麻烦了,只有所有类的基类Object才能装

//          Fruit a4 = superFruitPlate1.get();

            Object a5 = superFruitPlate1.get(); // 2*** 本质依然是强制转化,不过此处?是泛型的父类(或泛型本身),父类转子类需要强制转换,类型不安全,可调用方法可从子类中找,父类中不一定有,会有异常

      }

}

/**

 * declare a container

 * @author rq

 *

 * @param <T>

 */

class Plate<T>{

      private T item;

      public Plate(T t){

            this.item = t;

      }

      public T get(){return this.item;}

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

}

class Food{}

class Meat extends Food{}

class Fruit extends Food{}

class Apple extends Fruit{}

class Banana extends Fruit{}

class Pork extends Meat{}

class Beef extends Meat{}

class RedApple extends Apple{}

class GreenApple extends Apple{}

 

向上转型: 子类转父类,即父类的引用指向子类的实现。这种情况需要注意:引用能调用的内容是以父类为框架的,如果子类重写了父类的方法,那么调用子类本身的方法,如果没有则会调用父类方法(本质上还是子类方法,因为子类已经拥有了父类的特性),多态的一种重要实现手段。

 

乡下转型: 即父类转子类。需要强制转换,这种操作必须能知道父类中每个元素的类型才能保证安全,使用过程是,先子类向上转型,然后再向下转型。常用于容器,例如一个List<Animal>中装有Dog、Cat、Duck。。。,取出对象时进行强转,然后调用对应的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值