黑马程序员—泛型部分知识总结

来源:互联网 发布:手机如何查看淘宝等级 编辑:程序博客网 时间:2024/05/12 13:24
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
泛型部分知识总结

1、泛型好处

        我们可以在编辑类时不定义它内部的属性类型,定义方法时不再定义它的返回类型和传递的参数类型,定义接口时不再定义它们其下方法的返回类型。这些统统等实例化时再定义,不同的实例化对象可以实现不同的功能。之所以不用Object类,是因为Object类虽然可以接收所有类型,但是在运行类型拆装箱时存在着安全隐患,而这些在编译中是难以发觉的。比如下面的代码:

class Point{//我们来在2D平面中用不同方式表示一个点private Object x;//设置双轴坐标private Object y;public Object getX(){//返回横坐标return this.x;}public void setX(Object x){//设置横坐标this.x=x;}public Object getY(){return this.y;}public void setY(Object y){this.y=y;}}public class Text1{public static void main(String[] args){Point p = new Point();//实例化Point对象p.setY("20");p.setX(30);Text1.print(p);}public static void print(Point p){System.out.println("双倍Point:"+getIntX(p)*2+" "+getIntY(p)*2);}public static int getIntX(Point p){//转换整形int x=(Integer)p.getX();return x;}public static int getIntY(Point p){int y=(Integer)p.getY();return y;}}

        上面我们通过Object类像Int型数据的转换最终完成了在打印中*2的工作但是如果我们在传值的时候做了修改呢?

public class text1 {public static void main(String[] args) {Point p = new Point();//实例化Point对象p.setY("10");p.setX(20);p.print();}}

        虽然它会导致运行问题,但是编译肯定是能通过的,而这显然为我们带来了安全隐患

2、泛型定义类格式

定义类:class类名称<泛型标示>

实例化此类对象:类名称<具体类> 对象名称=new 类名称<具体类>();

修改后的代码如下:

class Point<T>{//我们来在2D平面中用不同方式表示一个点private T x;//设置双轴坐标private T y;public T getX(){//返回横坐标return this.x;}public void setX(T x){//设置横坐标this.x=x;}public T getY(){return this.y;}public void setY(T y){this.y=y;}}public class Text2{public static void main(String[] args){Point<Integer> p = new Point<Integer>();//实例化Point对象p.setY(40);p.setX(30);System.out.println("双倍Point:"+p.getX()*2+" "+p.getY()*2);}}

        这样一来,不但代码简单了不少,而且如果将p.setX(30);改成p.setX("30");这种错误的传值则则会直接产生编译错误,而不会在运行时发生。

3、泛型定义构造方法格式:

   访问权限构造方法 (泛型类型 参数名称)

4、指定多个泛型类的格式:

   访问权限 class <泛型标识1,泛型标识2,……>

5、假如新建实例对象时不指定泛型类型

public class Text3{public static void main(String[] args){Point p = new Point();//实例化Point对象p.setY(40);p.setX(30);System.out.println("Point:"+p.getX()+" "+p.getY());}}

      会提示警告信息,但是不会影响运行,而系统会默认以Object类接收如下图:


6、泛型方法定义格式

        访问权限<泛型标识> 泛型标识 方法名称(泛型标识 参数名称)

如:public static<T> T/void fun(T t)

7、泛型类的嵌套

        我们可以将一个Info类设定多个泛型类型如Info<T R>,我们再次设定一个Demo<S>类,而在建立Demo的实例对象时,可以作为Demo<Info<String Integer>> s = newDemo<Info<String Integer>>();的格式来作为泛型的嵌套使用。


class Demo<T>{//设定两类泛型private T var;//T类泛型的参数public void setVar(T var){//设定传递T类返回参数varthis.var=var;}public T getVar(){return this.var;}public Demo(T var){//重载构造函数this.setVar(var);//当前Demo的实例对象运行参数传递}}class Haha<S>{private S x;public S getX(){return x;}public void setX(S x){this.x=x;}public Haha(S x){this.setX(x);}}public class Text5 {public static void main(String[] args){//嵌套Demo类用匿名函数返回Demo后返回Demo类属性值System.out.println(new Haha<Demo<String>>(new Demo<String>("孤枕难眠")).getX().getVar());}}

8、通配符及泛型上下限

        通配符<?>主要应用于为未设定接收参数类型的函数拓展其接收类型如以下代码:

import java.util.ArrayList;import java.util.Iterator;public class Text6 {public static void main(String[] args){ArrayList<String> al=new ArrayList<String>();ArrayList<Integer> all=new ArrayList<Integer>();al.add("haha");al.add("hehe");all.add(30);all.add(20);fun(al);fun(all);}public static void fun(ArrayList<?> a){Iterator<?> it=a.iterator();while(it.hasNext()){System.out.println(it.next());}System.out.println(a.size());}}

 

        以上代码中的fun()函数可以将接收所有类型的ArrayList结合并去遍历输出,当然了如果改成

public static <T>voidfun(ArrayList<T> a){

                             Iterator<T>it=a.iterator();

也是可以的,就相当于给此fun()方法作泛型设定

设定泛型的上下限中上下限主要是指的类型的继承关系的上下限,格式如下:

将之前类或方法格式中的泛型标示部分改成:

上限:=? extend 父类 //?类范围是某父类或其子类

下限:=? super 子类  //?类范围是某子类或其父类

        具体在此就不做举例了,大家可以建立子父类或者用API中现成的(如Namber其下的Integer、Float包装类等)来去验证一下被设定泛型上限或下限的类或方法的包容性。

9、泛型数组

        泛型数组表达格式: 泛型标识[]

咱们来做个练习,完成一个一维数组的操作类,其中可以加入类型的数据,实现查询功能:

class Mun<T>{public <T> T[]fun1(T...arg){//数组接收任何类型的参数return arg;}public <T> void fun2(T args[]){//数组遍历输出方法for(int i=0;i<args.length;i++){System.out.print(args[i]+" ");}}public void fun3(T o,T args[]){int a=0;for(int i=0;i<args.length;i++){//数组的查询位置方法if(args[i].equals(o)){a++;System.out.println(o+"在数组中的位置是从左数的第"+(i+1)+"位");}}if(a==0){System.out.println("此数组中不包含元素"+o);}}}public class Text7 {public static void main(String[] args){Mun<Integer> t=new Mun<Integer>();Integer i[]=t.fun1(1,2,3,4);t.fun3(3, i);Mun<Double> t2=new Mun<Double>();Double i1[]=t2.fun1(1.0,2.0,3.0,4.0);t2.fun3(4.0,i1);t2.fun3(3.1, i1);}}

最后希望以上的部分知识总结能给大家帮助,与君共勉。



---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net
0 0