当前位置: 首页 > news >正文

泛型的定义,继承,通配符和综合练习(含笔记)

1、泛型

(1)引入:在没有泛型的时候,当你把一个对象放进java的集合中,集合就会忘记对象的类型,把所有的对象当做Object类型处理,这时可以把所有的类型放进集合。因此取出集合元素后通常还需要进行强制类型转换(调用子类特有功能时),这种强制类型转换不仅增加了编程的复杂度,还可能引发ClassCastException类型转换异常。所以java5引入了“参数化类型”即泛型(Generic)

泛型:可以在编译阶段约束操作的数据类型进行检查

泛型的格式:<数据类型>

注意:泛型只能支持引用数据类型,如果要操作基本数据类型,则需转换为对应包装类

扩展知识:java中的泛型是泛型。即这个泛型只在编译期间有效,它会在编译期间检查是否为该约束数据类型,而当编译结束,数据添加成功时集合还是会把这些数据当做Object类型来处理,只不过当再次获取数据时,集合的底层会把这些 Object类型的数据按照泛型进行强制转换。该行为叫做泛型的擦除

细节

  • 泛型中不能写基本数据类型,只有写对应的包装类才可以.(自定义类属于引用数据类型)

  • 指定泛型的具体类型后,传递数据时,可以传入该类类型或者其子类类型.

  • 如果不写泛型,默认类型是Object,

泛型定义:

定义在类后面 泛型类

定义在方法上面 泛型方法

定义在接口后面 泛型接口

2、泛型的定义

(1)泛型类

使用场景:当一个类中,某个变量的数据类型不能确定时,就可以定义带有泛型的类

定义泛型类时可以声明多个类型class MyClass<T,E>{ }

格式:

修饰符 class 类名<类型> {

}

举例:public class ArrayList<E> {}创建该类对象时,E就确定类型

此处的E可以理解为变量,但是它不是用来记录数据的,而是记录数据的类型,可以写成T、E、K、V等

定义是不知道存什么类型

下面的代码就是在你创建泛型类对象的时候把你定义的数据类型传递给E。

泛型类型个数可以是多个class MyClass<T,E>{ }

import java.util.Arrays; import java.util.Iterator; public class Main { public static void main(String[] args) { /*MyArrayList<String> list = new MyArrayList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); System.out.println(list);*/ MyArrayList<Integer> list = new MyArrayList<>(); list.add(123); list.add(234); list.add(345); int i = list.get(1).intValue(); Integer j = Integer.valueOf(i); System.out.println(list.toString()); } } class MyArrayList<E> { Object[] obj = new Object[10]; int size; //E:表示不确定的类型,该类型在类名后面已经定义过了。 //e:形参的名字,变量名 public boolean add(E e){ obj[size++]=e; return true; } public E get(int index) { return (E)obj[index]; } @Override public String toString() { return Arrays.toString(obj); } }

(2)泛型方法

方法中形参类型不能确定时

  • 可以使用类名后面定义的泛型<E> (所有方法都能用

  • 可以在方法申明上定义自己的泛型 (只有本方法能用

格式:

修饰符<类型> 返回值类型 方法名(类型 变量名) {

}

举例:当调用add方法的时候,才会确定T类型

public class MyArrayList {

public<T> boolean add(T e) {

obj[size++] = e;

return true;

}

}

import java.util.ArrayList; public class GenericsDemo1 { public static void main(String[] args){ ArrayList<String> list = new ArrayList<>(); ListUtil.addAll(list,"aaa","bbb","ccc"); System.out.println(list); ArrayList<Integer> list1 = new ArrayList<>(); ListUtil.addAll(list1,123,234,345,456,567,678,789); System.out.println(list1); } } class ListUtil { private ListUtil(){} //E...e可变参数,底层是一个数组,可以通过遍历获取每个元素。 public static<E> void addAll(ArrayList<E> list, E...e){ for (E element : e) { list.add(element); } } }

(3)泛型接口

当一个接口中类型不确定时,可以用在接口名后面加泛型

格式:修饰符 interface 接口名<类型> {

}

举例:public interface List<E> {}

重点:如何使用一个带泛型的接口

  • 方式一实现类给出具体类型

  • 方式二实现类延续泛型,创建对象时在确定

方式一:

import java.util.*; public class GenericsDemo2 { public static void main(String[] args){ MyArrayList2 list = new MyArrayList2();//实现类已经告诉具体类型,所以这里不用再用泛型 list.add("aaa"); list.add("bbb"); list.add("ccc"); System.out.println(list); } } class MyArrayList2 implements List<String> { @Override public boolean add(String stirng) { return false; } }

方法二:

import java.util.*; public class GenericsDemo3 { public static void main(String[] args) { //实现类延续接口泛型,不确定实现类是什么类型,此时需传入类型,使用泛型 MyArrayList3<String> list = new MyArrayList3<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); System.out.println(list); } } class MyArrayList3<E> implements List<E> { @Override public boolean add(E e) { return false; } }

3、泛型的继承和通配符

(1)泛型的继承

  • 泛型不具备继承性,但是数据具备继承性。所以说指定泛型的具体类型后,传递数据时,可以传入该类类型或者其子类类型.因为数据具备继承性。

import java.time.Year; import java.util.ArrayList; public class GenericsDemo4 { public static void main(String[] args){ ArrayList<Ye> list1 = new ArrayList<>(); ArrayList<Fu> list2 = new ArrayList<>(); ArrayList<Zi> list3 = new ArrayList<>(); method(list1); //下面调用方法会报错,因为泛型不具备继承性 // method(list2); // method(list3); //下面说明数据具备继承性 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)泛型的通配符

引入:下面代码中泛型方法有一个小弊端,此时他可以接受任意的数据类型,此时我们想要限定该方法的类型,所以就可以用泛型里面的通配符“?”实现。

通配符:?也表示不确定的类型,它可以进行类型的限定

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

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

举例:

(1)public static void method(ArrayList<?> list){}

等价于public static<E> void method(ArrayList<E> list){}因为?表示不确定的类型

(2)public static void method(ArrayList<? Extends Ye> list){} 表示可以传递E或者E所有的子类

(3)public static void method(ArrayList<? super Zi> list){} 表示可以传递Zi或者Zi所有的父类

应用场景:

  1. 如果我们定义类、方法、接口的时候,如果类型不确定、就可以定义泛型类、泛型方法。泛型接口。

  2. 如果类型不确定,但是能知道以后只能传递某个继承体系中的,就可以使用泛型的通配符。

泛型的通配符:

关键点:可以限定类型的范围

import java.util.ArrayList; public class GenericsDemo5 { public static void main(String[] args) { ArrayList<Yee> list1 = new ArrayList<>(); ArrayList<Fuu> list2 = new ArrayList<>(); ArrayList<Zii> list3 = new ArrayList<>(); ArrayList<Student> list4 = new ArrayList<>(); method(list1); method(list2); method(list3); method(list4); } //泛型方法有一个小弊端,此时他可以接受任意的数据类型。 public static<E> void method(ArrayList<E> list){ } //可以传递Ye和其所有的子类型Fu,Zi. public static void method(ArrayList<? Extends Ye> list){ } //可以传递Zi和其所有的父类型Fu,Ye public static void method(ArrayList<? super Zi> list){ } } class Yee { } class Fuu extends Yee { } class Zii extends Fuu { } class Student { }

(3)综合练习

import java.util.ArrayList; public class GenericsDemo6 { public static void main(String[] args) { ArrayList<BossCat> list1 = new ArrayList<>(); ArrayList<LihuaCat> list2 = new ArrayList<>(); ArrayList<TaidiDog> list3 = new ArrayList<>(); ArrayList<HashiDog> list4 = new ArrayList<>(); keepPer(list1); keepPer(list2); keepPer(list3); keepPer(list4); } public static void keepPer(ArrayList<? extends Animal> list){ } public static void keepPer(ArrayList<? extends Cat> list){ } public static void keepPer(ArrayList<? extends Dog> list){ } public static void keepPer(ArrayList<? super BossCat> list){ } public static void keepPer(ArrayList<? super TaidiDog> list){ } } class Animal { private String name; private int age; public Animal(){} public Animal(String name, int age) { this.name = name; this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void eat() { } } class Cat extends Animal { public Cat(String name, int age) { super(name, age); } } class Dog extends Animal { public Dog(String name, int age) { super(name, age); } } class BossCat extends Cat { public BossCat(String name, int age) { super(name, age); } @Override public void eat() { System.out.println("一只叫做" + getName() + "的" + getAge() + "岁的波斯猫,正在吃小饼干"); } } class LihuaCat extends Cat { public LihuaCat(String name, int age) { super(name, age); } @Override public void eat() { System.out.println("一只叫做" + getName() + "的" + getAge() + "岁的狸花猫,正在吃鱼"); } } class TaidiDog extends Dog { public TaidiDog(String name, int age) { super(name,age); } @Override public void eat() { System.out.println("一只叫做" + getName() + "的" + getAge() + "岁的泰迪狗,正在吃骨头"); } } class HashiDog extends Dog { public HashiDog(String name, int age) { super(name, age); } @Override public void eat() { System.out.println("一只叫做" + getName() + "的" + getAge() + "岁的哈士奇,正在吃肉"); } }
http://www.jsqmd.com/news/1046770/

相关文章:

  • 大数据行业就业前景分析
  • 上海地区春秋重型金属型材弯曲机市场口碑如何 - 工业品牌热点
  • 2026手提袋定制质量保证深度测评,零套路口碑推荐不踩雷 - mypinpai
  • 如何评估系统门窗十大品牌?靠谱生产商品牌解读 - myqiye
  • 我们是否还需要一个python的ggplot2?
  • 如何在5分钟内开始使用nHentai-cross跨平台漫画客户端
  • MC68340总线异常与仲裁机制:嵌入式系统稳定性的底层保障
  • Android权限管理架构解析:XXPermissions框架深度优化方案
  • 上海骏美玻璃纤维喷涂如何选择?专业支招 - 工业品牌热点
  • 深入解析TDA8026智能卡接口芯片:激活序列、故障检测与多卡槽应用实践
  • 3D卷积神经网络说话人识别部署实战:生产环境中的说话人验证系统搭建指南
  • TP-LINK 路由器忘记密码 - 恢复出厂设置
  • 深聊2026年可靠中型PLC品牌,亿维自动化靠谱吗 - myqiye
  • Kaggle上用Unsloth微调Qwen3的实战指南
  • Kaggle免费GPU微调Qwen3:Unsloth加速QLoRA实战指南
  • AI Agent 到底是什么?5分钟搞懂从大模型到智能体的进化之路
  • 旧手机跑AI助手:OpenClaw轻量级Agent本地部署实战
  • 地锅鸡连锁饭店出餐品质哪家高,2026十大出餐品牌深度测评,所见即所得不踩雷 - mypinpai
  • Openclaw+Kimi:199元打造可编程AI工作流中枢
  • 2026年徐州市CPPM考试最新全攻略:科目题型、通过率、备考重点及官方双认证报考机构推荐 - 众智商学院课程中心
  • QtScrcpy终极指南:免费实现电脑键鼠操控安卓手机的完整方案
  • AI Agent本地开发实战:Cherry Studio、Kelivo与LobeHub避坑指南
  • 如何选择电机定转子厂家?晟丰电气值得考虑 - 工业品牌热点
  • VMware vSphere安全攻防实战:从漏洞利用到纵深防御体系构建
  • 跨平台中文字体一致性挑战与PingFangSC字体技术解决方案
  • 新手必看!如何用AlphaTechnolog‘s dotfiles打造专属Linux工作空间:从入门到精通
  • 北京靠谱犬舍选购宠攻略,避坑指南全城十一家门店完整推荐 - 北京同城宠物基地
  • 2026年值得信赖的懂鸡帝火锅鸡品牌推荐,体验服务品质之选 - mypinpai
  • Python实战栈缓冲区溢出:从原理到CCProxy漏洞利用脚本编写
  • DeepSeek-V3 MoE架构落地实战:通信、负载与路由的工程破局