泛型的通配符和综合练习

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

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()+"岁的泰迪,正在吃骨头,边吃边蹭");
    }
}

三.总结:


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值