🍬 博主介绍
👨🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~
✨主攻领域:【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】
🎉点赞➕评论➕收藏 == 养成习惯(一键三连)😋
🎉欢迎关注💗一起学习👍一起讨论⭐️一起进步📝文末有彩蛋
🙏作者水平有限,欢迎各位大佬指点,相互学习进步!
目录
泛型的继承和通配符
动物集合练习
总结
泛型的继承和通配符
- 泛型不具备继承性,但是数据具备继承性
* ?也表示不确定的类型
* 他可以进行类型的限定
* ? extends E: 表示可以传递E或者E所有的子类类型
* ? super E:表示可以传递E或者E所有的父类类型
public static<E> void method(ArrayList<? extends GenericsDemo5.Ye> list){
}
泛型类GenericsDemo5
package list;
import java.util.ArrayList;
public class GenericsDemo5 {
public void main(String[] args) {
/*
泛型不具备继承性,但是数据具备继承性
*/
//创建集合的对象
ArrayList<Ye> list1 = new ArrayList<Ye>();
ArrayList<Fu> list2 = new ArrayList<Fu>();
ArrayList<Zi> list3 = new ArrayList<Zi>();
//调用method方法
method(list1);
//method(list2);
//数据继承
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{
}
}
泛型类:GenericsDemo6
package list;
import java.util.ArrayList;
public class GenericsDemo6 {
public static void main(String[] args) {
/*
* 需求:
* 定义一个方法,形参是一个集合,但是集合中的数据类型不确定。
*
* */
//创建集合的对象
ArrayList<GenericsDemo5.Ye> list1 = new ArrayList<GenericsDemo5.Ye>();
ArrayList<GenericsDemo5.Fu> list2 = new ArrayList<GenericsDemo5.Fu>();
ArrayList<GenericsDemo5.Zi> list3 = new ArrayList<GenericsDemo5.Zi>();
method(list1);
method(list2);
method(list3);
}
/*
* 此时,泛型里面写的是什么类型,那么只能传递什么类型的数据。
* 弊端:
* 利用泛型方法有一个小弊端,此时他可以接受任意的数据类型
* Ye Fu Zi Student
*
* 希望:本方法虽然不确定类型,但是以后我希望只能传递Ye Fu Zi
*
* 此时我们就可以使用泛型的通配符:
* ?也表示不确定的类型
* 他可以进行类型的限定
* ? extends E: 表示可以传递E或者E所有的子类类型
* ? super E:表示可以传递E或者E所有的父类类型
*
* 应用场景:
* 1.如果我们在定义类、方法、接口的时候,如果类型不确定,就可以定义泛型类、泛型方法、泛型接口。
* 2.如果类型不确定,但是能知道以后只能传递某个继承体系中的,就可以泛型的通配符
* 泛型的通配符:
* 关键点:可以限定类型的范围。
*
* */
public static<E> void method(ArrayList<? extends GenericsDemo5.Ye> list){
}
}
动物集合练习
test1测试类:
package Test;
import java.util.ArrayList;
import java.util.List;
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:该方法能养所有的动物,但是不能传递其他类型
*/
ArrayList<lihuaCat> list1 = new ArrayList<>();
ArrayList<hashiqiDog> list2 = new ArrayList<>();
// keepPet(List1);
// keepPet(List2);
}
//该方法能养所有的动物,但是不能传递其他类型
public static void keepPet(ArrayList<? extends Animal> list){
//遍历集合,调用动物的eat方法
}
/* // 要求2:该方法能养所有品种的狗,但是不能养猫
public static void keepPet(ArrayList<? extends Dog> list){
//遍历集合,调用动物的eat方法
}*/
/*//要求1:该方法能养所有品种的猫,但是不能养狗
public static void keepPet(ArrayList<? extends Cat> list){
//遍历集合,调用动物的eat方法
}*/
}
爷 类:Animal
package Test;
public abstract class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
public abstract void eat();
public String toString() {
return "Animal{name = " + name + ", age = " + age + "}";
}
}
父类:Cat
package Test;
public abstract class Cat extends Animal{
}
子类:bosiCat
package Test;
public class bosiCat extends Cat{
@Override
public void eat() {
System.out.println("一只叫做" + getName() + "的" + getAge() + "岁的波斯猫,正在吃小饼干");
}
}
子类:lihuaCat
package Test;
public class lihuaCat extends Cat{
@Override
public void eat() {
System.out.println("一只叫做" + getName() + "的" + getAge() + "岁的狸花猫,正在吃小鱼干");
}
}
父类:Dog
package Test;
public abstract class Dog extends Animal{
}
子类:taidiDog
package Test;
public class taidiDog extends Dog{
@Override
public void eat() {
System.out.println("一只叫做" + getName() +"的" + getAge()+"岁的泰迪,正在吃骨头,边吃边蹭");
}
}
子类:hashiqiDog
package Test;
public class hashiqiDog extends Dog{
@Override
public void eat() {
System.out.println("一只叫做" + getName() +"的" + getAge()+"岁的哈士奇,正在吃骨头,边吃边蹭");
}
}
总结
1.什么是泛型?
- 并进行检查JDK5引入的特性,可以在编译阶段约束操作的数据类型
2.泛型的好处?
-
统一数据类型
-
把运行时期的问题提前到了编译期间,避免了强制类型转换可能出现的异常,因为在编译阶段类型就能确定下来
3.泛型的细节?
-
泛型中不能写基本数据类型
-
可以传入该类型和他的子类类型指定泛型的具体类型后,传递数据时,
-
如果不写泛型,类型默认是Object
4.哪里定义泛型?
- 泛型类:在类名后面定义泛型,创建该类对象的时候,确定类型
- 泛型方法:在修饰符后面定义方法,调用该方法的时候,确定类型
- 泛型接口:在接口名后面定义泛型实现类确定类型,实现类延续泛型
5.泛型的继承和通配符
-
泛型不具备继承性但是数据具备继承性
-
泛型的通配符:?
? extend E
? super E
6.使用场景
- 定义类、方法、接口的时候,如果类型不确定,就可以定义泛型
- 如果类型不确定,但是能知道是哪个继承体系中的,可以使用泛型的通配符