JAVA 集合的进阶 泛型的继承和通配符

发布于:2025-05-31 ⋅ 阅读:(19) ⋅ 点赞:(0)

1 泛型通配符

可以对传递的类型进行限定

1.1 格式

?                               表示不确定的类型
?extends   E:       表示可以传递 E 或者 E 所有的子类类型
?super E:             表示可以传递 E 或者 E 所有的父类类型

1.2 应用场景

  • 如果我们在定义类、方法、接口的时候,如果类型不确定,就可以定义泛型类、泛型方法、泛型接口。
  • 如果类型不确定,但是能知道以后只能传递某个继承体系中的,就可以泛型的通配符

泛型的通配符:关键点:可以限定类型的范围。

1.3 练习

父类 

package com.bjpowernode.test17;

public abstract class Animal {
    private String name;
    private int age;

    public Animal() {
    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public abstract void eat();
}

子类

package com.bjpowernode.test17;

public abstract class Cat extends Animal{   //不要在这里重写 eat 方法,也写成抽象类!!
    //1.继承抽象类,重写里面所有的抽象方法
    //2.本身Cat也是一个抽象的,让Cat的子类再重写重写方法
    //因为猫的两个子类中eat的方法体还是不一样的。

}
package com.bjpowernode.test17;

public abstract class Dog extends Animal {
}
package com.bjpowernode.test17;

public class PersianCat extends Cat {
    @Override
    public void eat() {
        System.out.println("一只叫做" + getName() + "的," + getAge() + "岁的波斯猫,正在吃小饼干");
    }
}
package com.bjpowernode.test17;

public class LiHuaCat extends Cat {
    @Override
    public void eat() {
        System.out.println("一只叫做" + getName() + "的," + getAge() + "岁的狸花猫,正在吃🐟");
    }
}
package com.bjpowernode.test17;

public class HuskyDog extends Dog {
    @Override
    public void eat() {
        System.out.println("一只叫做" + getName() + "的," + getAge() + "岁的哈士奇 ,正在吃骨头,边吃边拆家");
    }
}
package com.bjpowernode.test17;

public class TeddyDog extends Dog {
    @Override
    public void eat() {
        System.out.println("一只叫做" + getName() + "的," + getAge() + "岁的泰迪,正在吃骨头");
    }
}

测试类

package com.bjpowernode.test17;


import java.util.ArrayList;

public class test {
    public static void main(String[] args) {
        ArrayList<LiHuaCat> list1 = new ArrayList<>();
        ArrayList<HuskyDog> list2 = new ArrayList<>();

        keepPet(list1);
        keepPet2(list2);
        keepPet3(list1);
        keepPet3(list2);
    }

    ///要求1:该方法能养所有品种的猫,但是不能养狗
    public static void keepPet(ArrayList<? extends Cat> list){

    }

    //要求1:该方法能养所有品种的狗,但是不能养猫
    public static void keepPet2(ArrayList<? extends Dog> list){

    }

    //该方法能养所有的动物,但是不能传递其他类型
    public static void keepPet3(ArrayList<? extends Animal> list){

    }
}

2 总结

  • 泛型不具备继承性但是数据具备继承性
  • 泛型中不能写基本数据类型
  • 指定泛型的具体类型后,传递数据时,可以传入该类型和他的子类类型
  • 如果不写泛型,类型默认是Object
  • 泛型的通配符:?
  • ? extend E
  • ? super E
  • 定义类、方法、接口的时候,如果类型不确定,就可以定义泛型
  • 如果类型不确定,但是能知道是哪个继承体系中的,可以使用泛型的通配符

参考链接:

集合进阶-09-泛型的通配符和综合练习_哔哩哔哩_bilibili