java extend 和 super

发布时间:2024年01月20日

基础:

extend 关键字,使用关键字extend继承父类的所有公共方法与公共字段。对于:

● 构造方法不能被继承,子类要重写

● 父类的私有属性不能被继承。

● 使用final声明的类是最终类,也不能被继承

super关键字来实现对父类成员的访问,用来引用当前对象的父类

一个是继承,一个是引用。

常见符号:

E - Element(在集合中使用,因为集合中存放的是元素)

T - Type (Java类)

K - Key(键)

V - Value(值)

N - Number(数值类型)

? - 表示不确定的java类型(无限制通配符类型)

PECS原则

假设现在有这么一个类的继承树,Fruit -> Apple -> RedApple/GreenApple

类:

Apple?
public class Apple extends Fruit {
    private Double price;
    public Apple(Double price) {
        this.price = price;
        this.show();
    }
    public Double getPrice() {
        return price;
    }
    @Override
    public void show() {
        System.out.println("I am an app");
    }
}
GreenApple
public class GreenApple extends Apple {
    public GreenApple(Double price) {
        super(price);
    }
    
    @Override
    public void show() {
        System.out.println("I am a green apple");
    }
}
RedApple
public class RedApple extends Apple {
   public RedApple(Double price) {
       super(price);
    }
    @Override
    public void show() {
        System.out.println("I am a red apple");
    }
}

测试

List<? extends Fruit> 意思: List中所有元素都是Fruit的子类(包含本身), 
List<? super Fruit> 意思: List中所有元素都是Fruit的父类(包含本身)
public static void main(String[] args) {
        // 申明父类,使用extend的时候,里面的元素都是Fruit的子类,无法识别
//         List <? extends Fruit> appList2 = new ArrayList<>();
//         appList2.add(new Apple(6.0));
//         appList2.add(new RedApple(8.5));
        List <? super Fruit> appList3 = new ArrayList<>();
        appList3.add(new Apple(6.0));
        appList3.add(new RedApple(7.5));
        appList3.add(new GreenApple(4.0));
        System.out.println(JSON.toJSONString(appList3));
        Object object = appList3.get(1);
        System.out.println(JSON.toJSONString(object));
}

? ?

“?”不能添加元素

/*
    1. “?”不能添加元素
        以“?”声明的集合,不能往此集合中添加元素,只能读,所以它只能作为生产者(亦即它只能被迭代),如下:
     */
    public static void testGeneric() {
        List<?> names = Lists.newArrayList("aaa", "yan");
//                 names.add("ccc"); // 报错无法进行添加
        //  通配符声明的集合,获取的元素都是Object类型
        List<Object> allNames = Lists.newArrayList("aaaa");
        allNames.addAll(names);
        //  只能以Object迭代元素
        for (Object name : allNames) {
            System.out.println(name);
        }
        System.out.println("==============testGeneric===============");
    }

“? extends T”也不能添加元素

/*
“? extends T”也不能添加元素
    以“? extends T”声明的集合,不能往此集合中添加元素,所以它也只能作为生产者
 */
public static void testGenericExtend() {
    List<? extends String> names = Lists.newArrayList("bbb");
    //        names.add("yan"); // 报错,无法进行添加
    //  声明消费者
    List<String> allNames = Lists.newArrayList("bbbb");
    //  消费生产者的元素
    allNames.addAll(names);
    allNames.forEach(System.out::println);
    System.out.println("==============testGenericExtend===============");
}

“? super T”能添加元素

/*
“? super T”能添加元素
在通配符的表达式中,只有“? super T”能添加元素,所以它能作为消费者(消费其他通配符集合)。
 */
public static void testGenericSuper() {
    List<? super String> allNames = Lists.newArrayList("bbb");
    //  可以直接添加本类及其父元素
    allNames.add("yan");
    //  可以直接添加泛型元素
    List<String> names = Lists.newArrayList("bbbb");
    //  也可以添加通配符泛型元素
    allNames.addAll(names);
    List<? extends String> names1 = Lists.newArrayList("cccc");
    allNames.addAll(names1);
    //  只能以Object迭代元素,因为是Object类型,就难以继续其它操作
    for (Object name : allNames) {
        System.out.println(name);
    }
    System.out.println("==============testGenericSuper===============");
}

总结:

????????生产者使用“? extends T”通配符,消费者使用“? super T”通配符

总结PECS原则如下:

? ? ?如果要从集合中读取类型T的数据,并且不能写入,可以使用 ? extends 通配符;(Producer Extends)

? ? 如果要从集合中写入类型T的数据,并且不需要读取,可以使用 ? super 通配符;(Consumer Super)

? ? 如果既要存又要取,那么就不要使用任何通配符。

文章来源:https://blog.csdn.net/qq_35461948/article/details/135697582
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。