1.5.泛型的通配符和综合练习

Java—泛型、内部类、多继承 泛型、内部类 阅读详情

一.泛型的继承和通配符:

1.泛型不具备继承性,但是数据具备继承性:

package com.itheima.a04mygenerics;
​
import java.util.ArrayList;
​
public class GenericsDemo5 {
    public static void main(String[] args) {
        
        //创建集合的对象
        ArrayList<Ye> list1=new ArrayList<>();
        ArrayList<Fu> list2=new ArrayList<>();
        ArrayList<Zi> list3=new ArrayList<>();
        
        
        //调用method方法
        method(list1);
        /*
        method(list2);
        method(list3);
        method方法里不能传list2和list3,
        因为泛型不具备继承性
        method方法的形参里集合泛型为Ye类型,传递参数时就必须是Ye类型,不能是其他类型,他的子类也不行
        */
        
        
        //数据具有继承性
        /*list1的泛型为Ye类型,可添加Ye类型以及他的子类型(添加的是数据)*/
        list1.add(new Ye());
        list1.add(new Fu());
        list1.add(new Zi());
    }
    
    
    public static void method(ArrayList<Ye> list){
        
    }
    
}
​
class Ye{}
class Fu extends Ye{}
class Zi extends Fu{}
​

2.弊端:可以接收任意数据类型:

package com.itheima.a04mygenerics;
​
import java.util.ArrayList;
​
public class GenericsDemo6 {
    public static void main(String[] args) {
        /* 需求:
            定义一个方法,形参是一个集合,但是集合中的数据类型不确定
         */
​
        //创建集合的对象
        ArrayList<Ye> list1=new ArrayList<>();
        ArrayList<Fu> list2=new ArrayList<>();
        ArrayList<Zi> list3=new ArrayList<>();
        
        ArrayList<Student2> list4=new ArrayList<>();
        
        method(list1);
        method(list2);
        method(list3);
        
        method(list4);
    }
​
    
    /* 弊端:
        利用泛型方法有一个弊端,此时它可以接收任意的数据类型
        如Ye Fu Zi 以及Student2
     */
    public static<E> void method(ArrayList<E> list){
         //E就是代表不确定的数据类型
    }
}
​
class Ye{}
class Fu extends Ye{}
class Zi extends Fu{}
​
class Student2{}

3.弊端的修改方案:

package com.itheima.a04mygenerics;
​
import java.util.ArrayList;
​
public class GenericsDemo6 {
    public static void main(String[] args) {
        /* 需求:
            定义一个方法,形参是一个集合,但是集合中的数据类型不确定
         */
​
        //创建集合的对象
        ArrayList<Ye> list1=new ArrayList<>();
        ArrayList<Fu> list2=new ArrayList<>();
        ArrayList<Zi> list3=new ArrayList<>();
​
        ArrayList<Student2> list4=new ArrayList<>();
​
        method(list1);
        method(list2);
        method(list3);
​
        //method(list4);会报错-->因为list4的泛型是Student2,method里只能传泛型是Ye以及Ye的子类的
    }
​
​
    /* 弊端:
        利用泛型方法有一个弊端,此时它可以接收任意的数据类型
        如Ye Fu Zi 以及Student2
​
      此时希望:虽然本方法不确定类型,但是以后只希望传递Ye Fu Zi
      注:不能把方法的形参里的泛型用Ye,因为泛型不具备继承性
      
      此时->可以利用 泛型的通配符 解决:?也表示不确定的类型
                                 也可以进行类型的限定->两种写法:? extends E:表示可以传递E或者E所有的子类类型
                                                           ? super E:表示可以传递E或者E所有的父类类型
                                                           
                                                           
       泛型的通配符的应用场景:
          1.在定义类,方法,接口的时候,如果类型不确定,就可以定义为泛型类,泛型方法,泛型接口(此时是不想限定类型的范围)
          2.如果类型不确定,但是能知道以后只能传递某个继承体系中的,就可以使用泛型的通配符
       泛型的通配符:
          关键点:用来限定类型的范围                                                           
     */
    public static void method(ArrayList<? extends Ye> list){
         //泛型用?时,前面不用再写<?>
    }
}
​
class Ye{}
class Fu extends Ye{}
class Zi extends Fu{}
​
class Student2{}

4.泛型的通配符的应用场景:

1)在定义类,方法,接口的时候,如果类型不确定,就可以定义为泛型类,泛型方法,泛型接口(此时是 不想限定类型的范围)
2)如果类型不确定,但是能知道以后只能传递某个继承体系中的,就可以使用泛型的通配符(此时是想限定类型的范围)
泛型的通配符->关键点:用来限定类型的范围

5.泛型的通配符的总结:

泛型的通配符 :?表示不确定的类型 也可以进行类型的限定->两种写法:

                            ? extends E:表示可以传递E或者E所有的子类类型

                            ? super E:表示可以传递E或者E所有的父类类型


二.综合练习:

package com.itheima.a05test;
​
import java.util.ArrayList;
​
public class Test1 {
    public static void main(String[] args) {
        /*需求:
           定义一个继承结构:
                          动物
                  |                     |
                  猫                    狗
               |      |              |     |
             波斯猫    狸花猫        泰迪     哈士奇
​
           属性:名字,年龄
           行为:吃东西
                 方法体打印:一只叫做XXX的,X岁的波斯猫,正在吃小鱼干
                 方法体打印:一只叫做XXX的,X岁的狸花猫,正在吃鱼
​
                 方法体打印:一只叫做XXX的,X岁的泰迪,正在吃骨头,边吃边蹭
                 方法体打印:一只叫做XXX的,X岁的哈士奇,正在吃骨头,边吃边拆家
​
​
          测试类中定义一个方法用于饲养动物
            public static void keepPet(ArrayList<???> list){
                 //遍历集合,调用动物的eat方法
            }
​
           要求1:该方法能养所有品种的猫,但是不能养狗
           要求2:该方法能养所有品种的狗,但是不能养猫
           要求3:该方法能养所有的动物,但是不能传递其他类型
​
​
         */
​
        //1.猫
        ArrayList<BoSi> c1=new ArrayList<>();
        c1.add(new BoSi("张三",1));
        keepPet(c1);
        ArrayList<LiHua> c2=new ArrayList<>();
        c2.add(new LiHua("李四",2));
        keepPet(c2);
​
        //2.狗
        ArrayList<TaiDi> d1=new ArrayList<>();
        d1.add(new TaiDi("王五",3));
        keepPet(d1);
        ArrayList<HaShiQi> d2=new ArrayList<>();
        d2.add(new HaShiQi("赵六",4));
        keepPet(d2);
​
        //3.动物
        keepPet(c1);
        keepPet(c2);
        keepPet(d1);
        keepPet(d2);
    }
​
​
    /*
    //要求1:该方法能养所有品种的猫,但是不能养狗
    public static void keepPet(ArrayList<? extends Cat> list){
        //遍历集合,调用动物的eat方法
        for (Cat cat : list) {
            cat.eat();
        }
    }
    */
​
    /*
    //要求2:该方法能养所有品种的狗,但是不能养猫
    public static void keepPet(ArrayList<? extends Dog> list){
        for (Dog dog : list) {
            dog.eat();
        }
    }
    */
​
    //要求3:该方法能养所有的动物,但是不能传递其他类型
    public static void keepPet(ArrayList<? extends Animal> list){
        for (Animal animal : list) {
            animal.eat();
        }
    }
​
}

​
package com.itheima.a05test;
​
public abstract class Animal {
​
    /* public abstract class Animal<N,I>{
          private N name;
          private I age;
       }
    当name,age类型不确定时就可以定义泛型类,N和I表示泛型类型
     */
​
    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.itheima.a05test;
​
public abstract class Cat extends Animal{
    //
    public Cat(){}
    public Cat(String name,int age){
        super(name, age);
    }
​
    //
    @Override
    public abstract void eat();
}

package com.itheima.a05test;
​
public abstract  class Dog extends Animal{
    //
    public Dog(){}
    public Dog(String name,int age){
        super(name, age);
    }
​
    //
    @Override
    public abstract void eat();
}
​
package com.itheima.a05test;
​
public class BoSi extends Cat{
    //
    public BoSi(){}
    public BoSi(String name,int age){
        super(name,age);
    }
​
    //
    @Override
    public void eat(){
        System.out.println("一只叫做"+super.getName()+"的,"+
                super.getAge()+"岁的波斯猫,正在吃小鱼干");
    }
}

​
package com.itheima.a05test;
​
public class HaShiQi extends Dog{
    //
    public HaShiQi(){}
    public HaShiQi(String name,int age){
        super(name, age);
    }
​
    //
    @Override
    public void eat(){
        System.out.println("一只叫做"+super.getName()+"的,"+
                super.getAge()+"岁的哈士奇,正在吃骨头,边吃边拆家");
    }
}
​
package com.itheima.a05test;
​
public class LiHua extends Cat{
    //
    public LiHua(){}
    public LiHua(String name,int age){
        super(name, age);
    }
    @Override
    public void eat(){
        System.out.println("一只叫做"+super.getName()+"的,"+
                super.getAge()+"岁的狸花猫,正在吃鱼");
    }
}

package com.itheima.a05test;
​
public class TaiDi extends Dog{
    //
    public TaiDi(){}
    public TaiDi(String name,int age){
        super(name, age);
    }
​
    //
    @Override
    public void eat(){
        System.out.println("一只叫做"+super.getName()+"的,"+
                super.getAge()+"岁的泰迪,正在吃骨头,边吃边蹭");
    }
}

​

三.总结:


Java泛型&通配符 Java 泛型(Generics)是 JDK 5 引入的一个新特性,它提供了编译时类型安全检测机制,允许在编译时检测出非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。泛型擦除是指在编译过程中,Java 编译器会将泛型类型信息擦除,将泛型类型转换为原始类型(Raw Type),也就是去掉泛型参数的类型信息,使得在运行时无法获取泛型的实际类型参数。例如,编译器会在编译期间动态地将泛型 T 擦除为 Object 或将 T extends xxx 擦除为其限定的类型 xxx。 阅读详情

相关推荐

Java 泛型使用通配符

ArrayList<?泛型,JDK1.5新加入的,解决数据类型的安全性问题,其主要原理是在类声明时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。使用泛型时,泛型类型必须为引用数据类型,不能为基本数据类型,Java中的普通方法,构造方法,静态方法中都可以使用泛型,方法使用泛型之前必须先对泛型进行声明,可以使用任意字母,一般都要大写。在引入范型之前,要在类中的方法支持多个数据类型,就需要对方法进行重载,在引入范型后,可以解决此问题(多态),更进一步可以定义多个参数以及返回值之间的关系。

usertest1的博客 1066

Java:高级之泛型概念引入,泛型可以设置多个类型参数,泛型继承和泛型接口实现,限制泛型可用类型,泛型通配的方式,泛型方法,泛型方法限制泛型可用类型

目录页 泛型简介 泛型类 限制泛型可用类型 类型通配声明 泛型方法 问题引入 如果我们需要产生多个对象,每个对象的逻辑完全一样,只是对象内的成员变量的类型不同。那我们如何去做? 我们新建一个工程 做一个构造方法public Cls1(int a){ this.a =a; ...

m0_57089315的博客 6645

Java泛型的继承和实现操作示例

主要介绍了Java泛型的继承和实现操作,结合实例形式分析了java泛型类的继承以及泛型接口的实现相关操作技巧,需要的朋友可以参考下

【java基础】泛型的限制及其继承规则

对于上面的限制,大家不用全部背下来,再使用泛型的时候慢慢理解就好了关于泛型的更多知识,参考以下内容泛型程序设计基础类型擦除、桥方法、泛型代码和虚拟机泛型的限制及其继承规则泛型的通配符(extends,super,?泛型程序设计基础类型擦除、桥方法、泛型代码和虚拟机泛型的限制及其继承规则泛型的通配符(extends,super,?

秃头披风侠的博客 3806

关于影响力最大化问题中贪心算法的一些理解

在影响力最大化问题中(Influence Maximization,以下简称IM),贪心算法是最早提出的一种解决方法,并且一直沿用至今。它基于IM问题所具有的单调性(Monotonicity)和子模性(Submodularity)使用一种Hill Climbing策略,不断使用Monte Carlo模拟来寻找在当前情况下的具有最大传播范围的节点,添加至种子集合,得到最终结果,算法伪代码如下所示: 这里算法1其实并没有使用MonteCarlo模拟,而只是使用了贪心的策略...

nianjuan1990的专栏 2852

从零到一:如何用YOLOv8和PyQt5打造你的第一个花卉识别桌面应用

本文详细介绍了如何使用YOLOv8和PyQt5从零开始构建一个花卉识别桌面应用。涵盖环境搭建、数据准备、模型训练、界面设计、模型集成与性能优化等全流程,帮助开发者快速掌握深度学习目标识别技术的实际应用。

weixin_29048775的博客 453

Java 中泛型的继承

与方法类似,泛型类和泛型接口也是在定义类型参数的时候使用的都是形参,但是在使用泛型类和泛型接口的时候,比如定义引用变量、继承泛型类和实现泛型接口,就必须传入实参,而实参就是具体的类型,比如 String、Integer 等类,也可以是自定义类型。综上所述:注:为了方便,下面中的"泛型"均指代"泛型类和泛型接口"。泛型定义的时候使用形参,使用泛型的时候必须传入实参。public class MyGeneric { ... } // T就是一个自己随意命名的类型形参。

m0_46977298的博客 2160

ArcGIS 10.2 保姆级安装与破解教程(含License Manager启动失败解决方案)

本文提供ArcGIS 10.2中文版的保姆级安装与破解教程,详细讲解从环境检查到License Manager配置的全流程,特别针对License Manager启动失败等常见问题提供专业解决方案,帮助用户顺利完成地理信息系统软件的安装与激活。

weixin_26757925的博客 1180

Java泛型通配符深度解析:无限定、上界、下界通配符全面掌握

泛型通配符如同一个无形的手,操控着程序的行进方向,让程序的逻辑更加严密,更加安全。泛型通配符,顾名思义,它是泛型的一种特殊形式,用于表示各种类型的泛型。你可能会问,为什么我们需要它呢?其实,当我们在开发过程中,经常会遇到一种情况,就是我们无法确定一个集合的具体类型,或者我们需要表示任何类型的情况,这时候,泛型通配符就派上了用场。它的出现,不仅让我们的代码更加灵活,而且也让我们的程序更加健壮。在接下来的内容中,我们将会深入探讨泛型通配符的各种形式,包括无限定通配符、上界通配符和下界通配符。

万猫学社 3787

晶圆测试(wafer sort)全流程解析:从探针卡到良率统计的实战指南

本文详细解析了晶圆测试(wafer sort)的全流程,从探针卡选型到良率统计的实战指南。涵盖了12英寸先进制程产线的关键技术,包括探针卡系统、测试程序开发、产线自动化集成及数据分析,特别聚焦多站点并行测试的时序优化和接触阻抗异常排查,帮助工程师提升测试效率与准确性。

weixin_29279153的博客 731

SpyGlass CDC实战:如何用sgdc约束文件解决跨时钟域报错(附常见错误排查)

本文详细介绍了如何使用SpyGlass CDC工具链中的sgdc约束文件解决跨时钟域(CDC)报错问题。从基础约束文件架构到复杂场景调试,涵盖了时钟域定义、复位信号约束、Waiver策略等关键技巧,并附有常见错误排查方法,帮助工程师高效处理CDC验证挑战。

loss4bartender的博客 1148

JAVA泛型、泛型通配符、综合练习

是 jdk5 中引入的特性,可以在编译阶段 约束 操作的数据类型,并进行检查。

2301_79947226的博客 1041

【Pytorch】DCGAN实战(三):二次元动漫头像生成

文章目录1.实现效果2.环境配置2.1Python2.2Pytorch、CUDA2.3Python IDE3.具体实现3.1数据预处理(data.py)(1)导入包(2)定义数据类3.2模型Generator,Discriminator,权重初始化(model.py)(1)导入包(2)Generator(3)Discriminator(4)权重初始化3.3网络训练(net.py)(1)导入包(2)创建类3.4 主函数(main.py)(1)导入文件(2)定义超参数(3)实例化(4)进行训练4.训练过程4.1

qq_44031210的博客 4916

泛型通配符详解

为什么要用通配符呢? 在java中,数组是可以协变的,比如dog extends Animal,那么Animal[] 与dog[]是兼容的。而集合是不能协变的,也就是说List<Animal>不是List<dog>的父类,这时候就可以用到通配符了。 一、基本概念: 在学习Java泛型的过程中, 通配符是较难理解的一部分. 主要有以下三类: 1. 无边界的通配符(Unb...

jarniyy的博客 5468

行测测评——矩阵、圆形、环形三角图形数列推理解题技巧

写在前面:各大公司的测评做的让人眼花缭乱,很多题型都是第一次见,比如逻辑关系、信息推理,最难的要属找规律的数字推理了。根据B站UP主刘文超老师的课程,记录一下解题技巧。感谢UP主的无私奉献,原地址连接:https://www.bilibili.com/video/BV1it411M7o2?t=528&p=7 解题技巧: 从图形的上下、左右、交叉 角度进行尝试求解 基本法则是“加、减、乘、除、倍数、次方”六种形态。 一、有心数阵 解题技巧:周边数字通过某种运算得到中间数字 1.周边数..

涵盖了计算机专业基础知识、数学建模相关实践、复杂网络论文研究、LeetCode算法刷题经验、C语言开发经验、前端Vue、React框架开发实战相关知识 8642

一文吃透 OData Deep Insert:从框架原理到 ABAP 实战

本文面向ABAP工程师,解析OData服务中的Deep Insert技术。文章首先阐述Deep Insert的业务背景,说明其适用于父子层级数据必须成组创建的场景(如销售订单与行项目)。随后深入框架实现机制,介绍SAP Gateway如何通过CREATE_DEEP_ENTITY方法处理嵌套请求,并强调开发者的责任边界。通过销售订单案例,文章对比了Deep Insert与$batch的适用场景差异,提供请求负载示例和DPC_EXT实现骨架代码。最后给出MPC_EXT声明深结构的三种套路,以及事务处理和错误处理

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 225

泛型:了解泛型与通配符

一、引出泛型 1、什么是泛型: 一般的类和方法,只能使用具体的类型: 要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大。----- 来源《Java编程思想》对泛型的介绍。 泛型是在JDK1.5引入的新的语法,通俗讲,泛型:就是适用于许多许多类型。从代码上讲,就是对类型实现了参数化。 2、代码测试 实现一个类,类中包含一个数组成员,使得数组中可以存放任何类型的数据,也可以根据成员方法返回数组中某个下标的值? 思路: 我们以前学过的数组,只能存放

1226 5116

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Java泛型方法的定义和使用、泛型类、泛型接口、泛型方法、通配符、泛型的上界与下界

Java泛型方法的定义和使用、泛型类、泛型接口、泛型方法、通配符、泛型的上界与下界

weixin_49114503的博客 6844

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【Java基础】Java泛型和泛型通配符详解

Java泛型的详解,总结了泛型通配符所有的含义,以及用法,并且说明了各个用法之间的区别。

大脑不能为空 2744

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

泛型&通配符

泛型&通配符

weixin_44525733的博客 1553

【Java】泛型的继承和通配符

需求:定义一个方法,形参是一个集合,但是集合中的数据类型不确定。??> list) {有同学就想了:既然集合里面的数据类型不确定,那就可以利用我们刚刚学的泛型方法解决,告诉你,完全是可以的。// 泛型需要先定义,再使用:即先在修饰符后面定义 <E>,才能在形参中使用 E此时在测试类中添加都没有问题但是这种写法它会有一个小小的弊端:此时他可以接受任意的数据类型,例如Ye Fu Zi,甚至你定义的类不在继承结构中,例如Student,它也是可以传递过去的。

qq_39921135的博客 1655

Java 泛型(Generic) 自定义泛型类和泛型接口和泛型方法的使用、泛型通配符

Java 泛型(Generic)1.为什么要有泛型(Generic)1.没有使用功能泛型时2.使用泛型时3.泛型2.泛型的使用1.泛型的声明2.泛型的实例化:3泛型的几个重要使用1. 泛型类(含集合类)需要注意的点2.在集合中使用泛型3.自定义泛型类、泛型方法4.泛型类的继承5.泛型接口4.泛型通配符 1.为什么要有泛型(Generic) 1.没有使用功能泛型时 解决元素存储的安全性问题 在集合...

码农回顾 4761

泛型与通配符

一般的类和方法,只能使用具体的类型:要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大。------来源《Java编程思想》对泛型的介绍。 泛型是在 JDK1.5 引入的新的语法,通俗讲,泛型:就是适用于许多许多类型。从代码上讲,就是对类型实现了参数化。

Tgess的博客 1255

Java数据结构基础——泛型、通配符_java通配符和泛型

一般的类和方法,只能使用具体的类型: 要么是基本类型,要么是自定义的类。只接受 Number 的子类型作为 E 的类型,实参没有指定类型边界 E,可以视为 E extends Object。实现一个类,类中包含一个数组成员,使得数组中可以存放任何类型的数据,也可以根据成员方法返回数组中某个下标的值。使用Object数组的缺点有二,存放元素时可以存放任何类型的元素,再者,取出元素的时候需要手动强转。因此,Java的泛型机制是在编译级别实现的。注意:泛型时在编译的时候的一种机制,在运行时是没有泛型的概念的。

2401_89734329的博客 1405

Java泛型通配符和泛型限定

类型通配符 类型通配符一般是使用?代替具体的类型实参(此处是类型实参,而不是类型形参)。当操作类型时不需要使用类型的具体功能时,只使用Object类中的功能,那么可以用 ? 通配符来表未知类型。例如 List&lt;?&gt; 在逻辑上是List&lt;String&gt;、List&lt;Integer&gt; 等所有List&lt;具体类型实参&gt;的父类。 public class ...

爪哇菌的博客 7710

Java 泛型详解:泛型类、泛型方法、泛型接口、类型擦除与类型通配符

本文全面解析Java泛型,这是JDK1.5引入的类型参数化机制,通过`<类型>`语法实现编译期类型安全,运行期经“类型擦除”保障性能。内容涵盖泛型类、方法、接口的定义、语法与实现方式,详解无界、上界、下界通配符的特性与用法,分析类型擦除原理及泛型关键规则(如参数化类型无继承、泛型运行时擦除等)。掌握泛型可提升代码安全、可读性与复用性,是Java开发者进阶必备技能。

Vivian_0682的博客 1547
上一篇: 11.拼图游戏登录界面代码
下一篇: 数据结构概述
巧克力拌面
博客等级 码龄3年 1153粉丝 282原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值