泛型(一)之为何引入泛型

2020-05-04  本文已影响0人  极客天空

一 没有泛型的世界

以一个小故事背景 来慢慢阐述泛型引入必要性

春节临近,在上海工作的云南小伙小明要带山东女朋友第一次回老家过年,回家之前他特定嘱咐妈妈多准备些水果,因为女朋友爱吃水果,但没告诉具体的水果。因为云南盛产香蕉,平时家里经常吃香蕉,所以就没准备香蕉,而是准备了当地卖的比较贵的 山东红富士。然而,女朋友小丽因为知道云南盛产香蕉,满怀期待的认为一定会吃到很多香蕉。于是,就闹出了乌龙事件

二 以程序来阐述没有泛型的世界

  1. 主角登场
//小丽
public class Xiaoli extends Person {
    public void eat(Banana banana){
        //正准备高兴的吃香蕉的时候,发现是苹果,生气了
        System.out.println("小丽吃"+ banana);
    }

    @Override
    public String toString() {
        return "Xiaoli";
    }
}
//小明
public class XiaoMing extends Person{
   //取标准的盘子  让家人放水果
    public RawPlate getPlate(){
        return new RawPlate();
    }
    @Override
    public String toString() {
        return "XiaoMing";
    }
}
//小明妈妈
public class XiaoMingMa extends Person {
  //拿盘子放水果(默认苹果)
    public void addFruit(RawPlate rawPlate){
        rawPlate.set(new Apple());
    }
    @Override
    public String toString() {
        return "XiaoMingMa";
    }

  1. 招待引起的乌龙
  public void scene0(){
        Xiaoli xiaoli = new Xiaoli();
        XiaoMing xiaoMing = new XiaoMing();
        XiaoMingMa xiaoMingMa = new XiaoMingMa();

        RawPlate rawPlate = xiaoMing.getPlate();
        xiaoMingMa.addFruit(rawPlate);

        xiaoli.eat((Banana) rawPlate.get());
      
    }

虽然 能够编译通过,但运行出现错误

  Exception in thread "main" java.lang.ClassCastException: fastec.com.rrcc.generics.demo01.Apple cannot be cast to fastec.com.rrcc.generics.demo01.Banana
         at fastec.com.rrcc.generics.demo01.Test1.scene0(Test1.java:30)
         at fastec.com.rrcc.generics.demo01.Test1.main(Test1.java:19)

小丽只吃香蕉,所以方法只接受Banana,获取到的Apple 不能强转为香蕉

三 泛型引入 问题解决

准备一个智能的盘子 既可以装苹果、也可以装香蕉

  1. 盘子的改进
public interface Plate<T> {
    public void set(T t);
    public T get();
}

//标准盘子
public class RawPlate implements Plate{
    private List items = new ArrayList(10);

    public RawPlate(){

    }

    @Override
    public void set(Object fruit) {
        items.add(fruit);
    }

    @Override
    public Object get() {
        int index = items.size() -1;
        if(index>= 0){
            return (Fruit) items.get(index);
        }else{
            return null;
        }
    }

    @Override
    public String toString() {
        return "RawPlate{" +
                "items=" + items +
                '}';
    }
}

//智能盘子 
public class AIPlate<T> implements Plate<T> {
    List<T> items = new ArrayList<T>();

    public AIPlate() {
    }

    public AIPlate(T t) {
        items.add(t);
    }


    @Override
    public void set(T t) {
        items.add(t);
    }

    @Override
    public T get() {
        int index = items.size() -1;
        if(index>= 0){
            return items.get(index);
        }else{
            return null;
        }
    }

    @Override
    public String toString() {
        return "AIPlate{" +
                "items=" + items +
                '}';
    }
}
  1. 小明 与 妈妈 给盘子 与 装水果的方法 改进
public class XiaoMing extends Person{
    public RawPlate getPlate(){
        return new RawPlate();
    }
   //引入 泛型方法  
    public <T> AIPlate<T> getAIPlate(){
        return new AIPlate<T>();
    }
    @Override
    public String toString() {
        return "XiaoMing";
    }
}

public class XiaoMingMa extends Person {

    public void addFruit(RawPlate rawPlate){
        rawPlate.set(new Apple());
    }

    /**
     * 这里不是泛型方法,这只是一个普通方法,只是使用了AIPlate<Banana> 这个泛型类做形参而已
     * @param aiPlate
     */
    public  void addFruitToAi(AIPlate<Banana> aiPlate){
        aiPlate.set(new Banana());
    }


    @Override
    public String toString() {
        return "XiaoMingMa";
    }
}

3.问题解决 重新招待

 public void scene1(){
        Xiaoli xiaoli = new Xiaoli();
        XiaoMing xiaoMing = new XiaoMing();
        XiaoMingMa xiaoMingMa = new XiaoMingMa();

        AIPlate<Banana> aiPlate = xiaoMing.getAIPlate();
        xiaoMingMa.addFruitToAi(aiPlate);

         xiaoli.eat(aiPlate.get());

    }

代码上传至github

上一篇 下一篇

猜你喜欢

热点阅读