什么是PECS,细说Java中的extends和super

类的关系如下:

	private static class Food {
    }

    private static class Fruit extends Food {
    }

    private static class Apple extends Fruit {
    }

    private static class Lemon extends Fruit {
    }

包装类

private static class Box<T> {
        private final String boxName;

        private T thing;

        public Box(String boxName) {
            this.boxName = boxName;
        }

        public T getThing() {
            return thing;
        }

        public void setThing(T thing) {
            this.thing = thing;
        }
    }

PECS即Producer Extends Consumer Super
super,下界通配符(Lower Bounds Wildcards),Fruit及其基类属于下界
extends,上界通配符(Upper Bounds Wildcards),Fruit及其子类属于上界

  • 几个问题
  1. Box<? super Fruit> 能代表哪些类型
		new Box<Fruit>
        new Box<Food>
  1. Box<? extends Fruit> 能代表哪些类型
        new new Box<Fruit>
        new new Box<Apple>
        new new Box<Lemon>
  1. PECS指的是从集合视角,对集合来说是属于生产者(提供数据),还是属于消费者(使用数据)

    3.1 为什么生产者Producer(Box<? extends Fruit>),只能从集合里面get数据,而不能add数据?
    Box<? extends Fruit> box = new Box<>(“box1”);
    // box可能指向new new Box或new new Box或new new Box,
    // 我们不能保证里面存的具体是什么类型,只能保证拿出来的是Fruit类型

    3.2 为什么消费者Consumer(Box<? super Fruit>),只能add数据,不能从集合里面get数据?
    Box<? super Fruit> box = new Box<>(“box1”);
    box.add(new Fruit());
    // box可能指向new Box或new Box,但是其肯定能放置Fruit类型,所以能add数据
    // 但我们不能保证get出来的数据是Fruit类型(我们get就是为了取出特定类型的数据),可能是Fruit或Food,
    // 所以不能get泛型Fruit类型的数据,而不是不能get数据

    3.3 消费者(Box<? super Fruit>)都能add什么类型数据?
    Box<? super Fruit> box = new Box<>(“box1”);
    // box可能指向new Box或new Box,但是其肯定能放置Fruit类型
    box.add(new Apple());
    box.add(new Lemon());
    box.add(new Fruit());
    box.add(new Food()); // error

  • 测试代码
		// 可以指向Fruit及其基类
		Box<? super Fruit> box1 = new Box<Fruit>("box1");
        Box<? super Fruit> box2 = new Box<Food>("box1");
		// 可以指向Fruit及其子类
        Box<? extends Fruit> box11 = new Box<Fruit>("box1");
        Box<? extends Fruit> box12 = new Box<Apple>("box1");
        
        // 消费者,add数据的类型
		Box<? super Fruit> box = new Box<>("box1");
        box.setThing(new Apple());
        box.setThing(new Lemon());
        box.setThing(new Fruit());
        box.setThing(new Food()); // error
        // 消费者,无法get(Fruit类型的数据)
        Fruit fruit = box.getThing(); // error
        
        // 生产者,不能add
		Box<? extends Fruit> box2 = new Box<>("box2");
		box2.setThing(new Apple()); // error
  • refer
  • https://www.cnblogs.com/drizzlewithwind/p/6100164.html
  • https://*.com/questions/2723397/what-is-pecs-producer-extends-consumer-super
  • https://*.com/questions/2776975/how-can-i-add-to-list-extends-number-data-structures
上一篇:JAVA的PECS原则


下一篇:java – 是否可以编写一个接受不同抽象的泛型参数的方法?