继承泛型结构类的几种方式,泛型方法的定义和泛型中通配符的使用

本文探讨了Java中继承泛型结构类的几种方式,详细讲解了泛型方法的定义,并分析了泛型中通配符的使用,包括<?>、<? extends Animal>和<? super Animal>。通过示例代码展示了如何在实际编程中应用这些概念。

继承泛型结构类

这个继承关系可能会有点绕
第一行代码:首先祖父类GrandFather是一个泛型结构类,泛型参数为
第二行代码:父亲类继承了祖父类,而继承时泛型参数还是,子类继承后也需要加上泛型参数
第三行代码:儿子类又继承了父亲类,而继承父亲类时泛型参数指明了参数类型,即,则儿子类便不再需要加上泛型参数,但是儿子类可以自己加上自己或自己的后代的泛型,即:<E1, E2, E3>
第四行代码:儿子的儿子(SonIsSon)继承了儿子类<E1, E2, E3>,而这时继承时把第一个泛型E1指定为了String,SonIsSon类便不需要再重复指定泛型的类型,而SonIsSon也可以自己指定一个泛型R1

public class GrandFather<T> {}//祖父类
class Father<T> extends GrandFather<T>{}//父亲类
class Son<E1, E2, E3> extends Father<Integer> {}//儿子类:自己增加三个泛型E1,E2,E3
class SonIsSon<E2, E3, R1> extends Son<String, E2, E3>{}//儿子的儿子类:保留两个泛型E2,E3,自己增加一个R1

泛型方法

泛型方法的声明格式:public List getList(T[] arr){return null;}
1,声明泛型方法跟是否是在泛型类型类中声明无关,
2,声明泛型方法需要使用修饰
3,如果子类需要重写静态泛型方法,则静态泛型方法必须也使用static修饰

class AAA {
    public static <T>List<T> getList(T[] arr){//静态泛型方法
        return Arrays.asList(arr);
    }
}
class BBB extends AAA{
    public static <T>List<T> getList(T[] arr){//如果子类需要重写静态泛型方法,则静态泛型方法必须也使用static修饰
        return Arrays.asList(arr);
    }
}

泛型中通配符

解析
统配符几种方式
*通配符"?"*表示类型不确定
1. <?>,类型不确定,通常用在方法的参数中
2. <? extends Animal>,只允许泛型为Animal及Animal子类的引用调用
3. <? super Animal>,只允许泛型为Animal及Animal父类的引用调用
4. <? extends Comparable>,只允许泛型为实现Comparable(比较器)接口的实现类引用调用

1,<?>

首先方法中的<? extends Map.Entry<Integer, ?>>就是解析中的:<? extends Animal>,只是这里是导入的内部Entry类
其次代码中都有注释
这里不再赘述

详细代码

class Test{
    public static void main(String[] args) {
        //创建一个map集合
        Map<Integer,String> maps = new HashMap<>();
        maps.put(1,"AAA");//添加键值对
        maps.put(2,"BBB");
        maps.put(3,"CCC");
        show(maps);//调用show方法,泛型参数则是声明<Integer,String>的集合
    }
    public static void show(Map<Integer,?> map){//通配符"?"不确定的类型
        /*
         * 生成变量Set
         * 因为有一个类型是不确定的所以显示的是最大的范围即:Map.Entry<Integer, ?>;<? extends Map.Entry<Integer, ?>>
         * 其他泛型集合都一样适用于此方法的通配符使用方式
         * */
        Set<? extends Map.Entry<Integer, ?>> entries = map.entrySet();
        //获取迭代器对象
        Iterator<? extends Map.Entry<Integer, ?>> iterator = entries.iterator();
        //使用while循环,迭代器遍历Map键值对集合
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

    }
}

控制台输出

1=AAA
2=BBB
3=CCC

2,<? extends Animal> 和 <? super Animal>

这两个放在一起说

  1. 首先创建两个类分别为Animal和继承了Animal的Cat类
    2. 之后再main方法中创建三个不同泛型的集合
    3. 之后创建了使用通配符后的集合,证明了不能直接添加类型,只能添加null
    4. 创建泛型为<? extends Animal>和<? super Animal>的空的list集合
    5. 之后使用 “=” 进行赋值操作,因为需要保证不会出现数据类型的错误,可以发现分别赋值后:
    – 泛型为<? extends Animal>的list1不可 “=” 创建泛型为的array3集合,说明:只允许泛型为Animal及Animal子类的引用调用
    – 泛型为<? super Animal>的list2不可 “=” 创建泛型为的array2集合,说明:只允许泛型为Animal及Animal父类的引用调用
    – 跟解析的描述是一样的
    6. 可以复制,解开注释自己看一下

代码

class Animal{}//创建动物类Animal
class Cat extends Animal{}//创建继承了Animal的猫类
class Test{
    public static void main(String[] args) {
    	//创建泛型为<Animal>,List类型的ArrayList实例
        List<Animal> array1 = new ArrayList<>();
        //创建泛型为<Cat>,List类型的ArrayList实例
        List<Cat> array2 = new ArrayList<>();
        //创建泛型为<Object>,List类型的ArrayList实例
        List<Object> array3 = new ArrayList<>();
        
        List<? extends Animal> list= new ArrayList<>();
        //list1.add(new Animal());//编译失败!说明:使用通配符?之后不能直接添加类型
        list1.add(null);//只能添加Null
        
        //创建泛型为<? extends Animal>的空List集合
        List<? extends Animal> list1 = null;
        //创建泛型为<? super Animal>的空List集合
        List<? super Animal> list2 = null;

        list1 = array1;
        list1 = array2;
        //list1 = array3;//编译不成功,说明<? extends Animal>泛型不能引用Animal继承链之上的类型比如:Object

        list2 = array1;
        //list2 = array2;//编译不成功,说明<? super Animal>泛型不能引用Animal继承链之下的类型比如:继承了Animal的Cat类
        list2 = array3;
    }
}

3,<? extends Comparable>

  1. 创建实现了Comparable比较器接口的类:Students ,并重写comportTo方法
  2. 在GenericComparableTest 类中声明一个参数为 List<? extends Comparable> array 的show()方法
  3. 创建泛型为的集合,Students实现了Comparable接口
  4. 调用show()方法,将创建的集合放入
  5. 编译成功!如果Students没有实现Comparable接口不会进行编译

代码

public class GenericComparableTest {
    public static void main(String[] args) {
        //创建泛型为<Students>的集合,Students实现了Comparable接口
        ArrayList<Students> array = new ArrayList<>();
        show(array);//没有报错
    }

    //创建一个参数为List<? extends Comparable> array的show方法
    static void show(List<? extends Comparable> array){}
}

class Students implements Comparable<Students>{//继承比较器接口
    private String name;
    private int age;

    //重写equals比较方法
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Students students = (Students) o;
        return age == students.age &&
                Objects.equals(name, students.name);
    }
    //重写获得哈希值的方法
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
    //重写toString方法
    @Override
    public String toString() {
        return "Students{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    //实现Comparable后,实现的方法
    @Override
    public int compareTo(Students o) {
        return this.name.compareTo(o.name);//降序a-z排序
    }
}

PS:如果有错误请指正


END

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值