zoukankan      html  css  js  c++  java
  • 限制泛型可用类型,类型通配符声明,泛型方法

    一、限制泛型可用类型

    ①   在定义泛型类型时,默认在实例化泛型类的时候可以使用任何类型,但是如果想要限制使用泛型类型时,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义类型时,使用extends关键字指定这个类型必须是继承某个类,或者实现某个类;

    ②   当没有指定泛型继承的类型或接口时,默认使用extends Object,所以默认情况下任何类型都可以作为参数传入;

    继承抽象类

     1 public class GenericDemo3{
     2     public static void main(String []args){
     3         GenericClass<Dog> dogClass=new GenericClass<Dog>();
     4         dogClass.setObj(new Dog());
     5         dogClass.getObj().eat();
     6         
     7         
     8         GenericClass<Cat> catClass=new GenericClass<Cat>();
     9         catClass.setObj(new Cat());
    10         catClass.getObj().eat();
    11     }
    12 }
    13 
    14 //泛型类所接受的参数做了限制,只能接收Animal类型或者Animal类的子类
    15 class GenericClass<T extends Animal>{
    16     private T obj;
    17     public void setObj(T obj){
    18         this.obj=obj;
    19     }
    20     public T getObj(){
    21         return obj;
    22     }
    23 }
    24 
    25 abstract class Animal{
    26     public abstract void eat();
    27 }
    28 
    29 class Dog extends Animal{
    30     public void eat(){
    31         System.out.println("啃骨头");
    32     }
    33 }
    34 class Cat extends Animal{
    35     public void eat(){
    36         System.out.println("吃鱼肉");
    37     }
    38 }
    View Code

    继承接口

     1 public class GenericDemo3{
     2     public static void main(String []args){
     3         GenericClass<Dog> dogClass=new GenericClass<Dog>();
     4         dogClass.setObj(new Dog());
     5         dogClass.getObj().eat2();
     6         
     7         
     8         GenericClass<Cat> catClass=new GenericClass<Cat>();
     9         catClass.setObj(new Cat());
    10         catClass.getObj().eat2();
    11     }
    12 }
    13 
    14 //泛型类所接受的参数做了限制,只能接收Animal类型或者Animal类的子类
    15 class GenericClass<T extends Animal2>{
    16     private T obj;
    17     public void setObj(T obj){
    18         this.obj=obj;
    19     }
    20     public T getObj(){
    21         return obj;
    22     }
    23 }
    24 
    25 interface Animal2{
    26     public abstract void eat2();
    27 }
    28 
    29 class Dog implements Animal2{
    30     public void eat2(){
    31         System.out.println("啃骨头2");
    32     }
    33 }
    34 class Cat implements Animal2{
    35     public void eat2(){
    36         System.out.println("吃鱼肉2");
    37     }
    38 }
    View Code

    二、类型通配符声明

    ①   同一泛型类,如果实例化时给定的实际类型不同,则这些实例的类型是不兼容的,不能相互赋值;

    Generic<Boolean> f1=new Generic<Boolean>();

    Generic<Integer> f2=new Generic<Integer>();

    f1=f2;//发生编译错误

    Generic<Object> f=f1;//f1和f类型并不兼容,发生编译错误

    f=f2;//f2和f类型同样不兼容,也会发生编译错误

    ②   泛型类实例之间的不兼容性会带来使用的不便。我们可以使用泛型通配符(?)声明泛型类的变量就可以解决这个问题;

    ③   泛型通配符的方式

    “?”代表任意一个类型;

    Generic<Boolean> f1=new Generic<Boolean>();

    Generic<?> f=f1;

    和限制泛型的上限相似,同样可以使用extends关键字限定通配符匹配类型的上限;

    Generic<Dog> f1=new Generic<Dog>();

    Generic<? extends Animal> f=f1;

    还可以使用super关键字将通配符类型限定为某个类型及其父类型;

    Generic<Animal> f1=new Generic<Animal>();

    Generic<? super Dog> f=f1;

     1 public class GenericDemo4{
     2     public static void main(String []args){
     3         GenericClass<Dog> dogClass=new GenericClass<Dog>();
     4         dogClass.setObj(new Dog());
     5         dogClass.getObj().eat();
     6         
     7         GenericClass<Cat> catClass=new GenericClass<Cat>();
     8         catClass.setObj(new Cat());
     9         catClass.getObj().eat();
    10         
    11         GenericClass<String> StringClass=new GenericClass<String>();
    12         
    13         //dogClass=catClass;//编译出错
    14         
    15         //无限定通配符的使用
    16         GenericClass<?> gClass=null;
    17         gClass=dogClass;
    18         ((Dog)gClass.getObj()).eat();//因父类为object类型,所以要强制转换
    19         
    20         gClass=StringClass;
    21         
    22         //上边界限定通配符
    23         GenericClass<? extends Animal> subclass=null;
    24         subclass=dogClass; //Animal a=dog;
    25         subclass.getObj().eat();
    26         
    27         //下边界限定通配符
    28         GenericClass<? super Dog> sclass=null;
    29         GenericClass<Animal> cClass=new GenericClass<Animal>();
    30         //sclass=catClass; //编译错误,类型不兼容
    31         sclass=cClass;//可以通过编译
    32     }
    33 }
    34 
    35 
    36 class GenericClass<T>{
    37     private T obj;
    38     public void setObj(T obj){
    39         this.obj=obj;
    40     }
    41     public T getObj(){
    42         return obj;
    43     }
    44 }
    45 
    46 interface Animal{
    47     public abstract void eat();
    48 }
    49 
    50 class Dog implements Animal{
    51     public void eat(){
    52         System.out.println("啃骨头");
    53     }
    54 }
    55 class Cat implements Animal{
    56     public void eat(){
    57         System.out.println("吃鱼肉");
    58     }
    59 }
    View Code

    三、泛型方法

    ①   不仅类可以声明泛型,类中的方法也可以声明仅用于自身的泛型,这种方法叫做泛型方法。其定义格式为:

     

    访问修饰符<泛型列表> 返回类型 方法名(参数列表){

               实现代码

    }

    ②   在泛型列表中声明的泛型,可用于该方法的返回类型声明、参数类型声明和方法代码中的局部变量的类型声明;

    ③   类中其它方法不能使用当前方法声明的泛型;

    注:是否拥有泛型方法,与其所在的类是否泛型没有关系。要定义泛型方法,只需将泛型参数列表置于返回值前;

    ④   什么时候使用 泛型方法,而不是泛型类?

    添加类型约束只作用于一个方法的多个参数之间,而不涉及到类中的其它方法;

    施加类型约束的方法为静态方法,只能将其定义为泛型方法,因为静态方法不能使用其所在类的类型参数;

     1 public class GenericDemo5{
     2     public static void main(String []args){
     3         GenericClass2 gen=new GenericClass2();
     4         gen.println("abc");
     5         gen.println(true);
     6         gen.println(10);
     7         gen.println(10.5);
     8         gen.println(new Dog());
     9         gen.println(new Cat());
    10         GenericClass2.print("哈哈");
    11     }
    12 }
    13 
    14 class GenericClass2{
    15     //泛型方法
    16     public <T> void println(T content){
    17         System.out.println(content);
    18     }
    19     //泛型方法的重载
    20     public <T extends Animal> void println(T animal){
    21         animal.eat();
    22     }
    23     
    24     public static <T> void print(T content){
    25         System.out.println(content);
    26     }
    27 }
    28 
    29 interface Animal{
    30     public abstract void eat();
    31 }
    32 
    33 class Dog implements Animal{
    34     public void eat(){
    35         System.out.println("啃骨头");
    36     }
    37 }
    38 class Cat implements Animal{
    39     public void eat(){
    40         System.out.println("吃鱼肉");
    41     }
    42 }
  • 相关阅读:
    NYOJ 260
    NYOJ 271
    [转载]《博客园精华集》Winform筛选结果(共105篇)
    在DataGridView控件中加入ComboBox下拉列表框的实现
    给SQL补充一个查看表结构的存储过程
    编写自定义控件之下拉式属性
    PropertyGrid中的枚举显示为中文(转)
    DataGridView 中合并单元格
    树TreeView控件与DataTable交互添加节点(最高效的方法)
    通过键盘方向键控制TreeView节点的移动
  • 原文地址:https://www.cnblogs.com/wzy330782/p/5361104.html
Copyright © 2011-2022 走看看