Day18:泛型

认识泛型

泛型是JDK1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数,使代码可以应用于多种类型。简单说来,Java 语言引入泛型的好处是安全简单,且所有强制转换都是自动和隐式进行的,提高了代码的重用率。

定义:将对象的类型作为参数,指定到其他类或者方法上,从而保证类型转换的安全性和稳定性

1或者接口<类型实参>对象=new2<类型实参>();

注意
首先,“类2”可以是“类1”本身,可以是“类1”子类,还可以是接口的实现类;其次,“类2”的类型实参必须与“类1”中的实参相同。

ArrayList<String>list=new ArrayList<String>();

上述代码表示江川一个ArrayList集合,但规定该集合中存储的元素类型必须为String类型。xxx

泛型集合

使用泛型集合在创建集合对象时指定集合中元素的类型,从集合中取出元素时无需进行强制类型转换,并且如果把非指定类型对象放入集合,会出现编译错误。

泛型集合可以约束集合内的元素类型
典型泛型集合ArrayList、HashMap<K,V>
、<K,V>表示该泛型集合中的元素类型
泛型集合中的数据不再转换为Object
➢存储数据时进行严格类型检查,确保只有合适类型的对象才能存储在集合中。
➢从集合中检索对象时,减少了强制类型转换。

深入泛型

在集合中使用泛型只是泛型多种应用的一种,在接口、类、方法等方面也有着泛型的广泛应用。泛型的本质就是参数化类型,参数化类型的重要性在于允许创建一些类、接口和方法,其所操作的数据类型被定义为参数,可以在真正使用时指定具体的类型。在学习如何
➢参数化类型:参数化类型包含一个类或者接口,以及实际的类型参数列表。
➢类型变量:是一种非限定性标识符,用来指定类、接口或者方法的类型。
泛型标记;

  • T 所有类Objec+所有接口
  • E 所有Java本有(不是自己定义的)类
  • K 键
  • V 值

1.定义泛型类、泛型接口和泛型方法

对于一些常常处理不同类型数据转换的接口或者类,可以使用泛型定义,如Java中的List接口。定义泛型接口或类的过程,与定义一个接口或者类相似。

(1)泛型类
泛型类简单地说就是具有一个或者多个类型参数的类。
定义泛型类的语法格式如下。

扫描二维码关注公众号,回复: 11575365 查看本文章
访问修饰符class className<TypeList>

TypeList表示类型参数列表,每个类型变量之间以逗号分隔。
例如:

public class GenericClass<T> ...

创建泛型类实例的语法格式如下:

new className<TypeList>(argList);

➢TypeList 表示定义的类型参数列表,每个类型变量之间以逗号分隔。
➢argList 表示实际传递的类型参数列表,每个类型变量之间同样以逗号分隔。例如:

new GenericClass<String>("this is String object")

(2)泛型接口
泛型接口就是拥有一个或多 个类型参数的接口。泛型接口的定义方式与定义泛型类类似。
定义泛型接口的语法格式如下。

访问修饰符interface interfaceName<TypeList>

TypeList表示由逗号分隔的一个或多 个类型参数列表。
例如:

public interface TestInterface<T>{
public T print(T t);

泛型类实现泛型接口的语法格式如下。

访问修饰符class className<TypeList>implements interfaceName<TypeList>

示例13
定义泛型接口、泛型类,泛型类实现泛型接口,在泛型类中添加相应的泛型方法。
实现步骤如下。
添加方法rface,
1)定义泛型接口Testinterface, 添加方法getName(),并设置返回类型为T。
2)定义泛型类Sudent,并实现接口TestInterface,声明类型为T的字子段name,添加构造方法。
3)使用Student实例化TestInterface。
关键代码:

interface TestInterface<T> {
    //定义泛型接口
    public T getName();//设置的类型由外部决定
}

//定义泛型类
class Student<T> implements TestInterface<T> {//实现接口TestInterface<T>
    private T name;//设置的类型由外部决定

    public Student(T name) {
        this.setName(name);
    }


    public void setName(T name) {
        this.name = name;
    }

    public T getName() {          //返回类型由外部决定

        return this.name;
    }
}

public class GenericesClass {
    public static void main(String[] args) {
        TestInterface<String> student = new Student<String>("张三");//①
        System.out.println(student.getName());

    }
}

输出结果:张三
在示例13中,①的代码用来创建Student对象,Student泛型类的泛型参数定义为Sring类型,执行此代码后, TestInterface接口和Student类中的泛型参数类型都为String。并会通过Student类中只有一个String参数的构造方法来创建对象,则name属性的值为“张三”。
(3)泛型方法
一些方法常常需要对某一类型数据进行处理,若处理的数据类型不确定,则可以通过泛型方法的方式来定义,达到简化代码、提高代码重用性的目的。

泛型方法实际上就是带有类型参数的方法。需要特别注意的是, 定义泛型方法与方法所在的类、或者接口是否是泛型类或者泛型接口没有直接的联系,也就是说无论是泛型类还是非泛型类,如果需要就可以定义泛型方法。
定义泛型方法的语法格式如下。

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

例如:

public <String> void showName(String s){ }

注意在泛型方法中,类型变量放置在访问修饰符与返回值之间。
示例14
定义泛型方法并调用。
实现步骤如下。
1)定义泛型方法。
2)调用泛型方法。
关键代码:

public class GenericMethod {
    //定义泛型方法
    public <Integer> void showSize(Integer o) {
        System.out.println(o.getClass().getName());
    }

    public static void main(String[] args) {
        GenericMethod gm = new GenericMethod();
        gm.showSize(10);
    }
}

输出结果:
java.lang. Integer

2.多个参数的泛型类

前面的示例中,泛型类的类型参数都只有一个,实际上类型参数可以有多个,如HashMap<K,V>就有两个类型参数,一个 指定key 的类型,一个指定 value的类型。下面介绍如何自定义一个包含多个类型参数的泛型类。
示例15
定义泛型类,并设置两个类型参数。
实现步骤如下。
(1)定义泛型类。
(2)实例化泛型类。
关键代码:


class GenericDemo<T, V> {
    private T a;
    private V b;

    public GenericDemo(T a, V b) {
        this.a = a;
        this.b = b;
    }

    public void showType() {

        System.out.println("a 的类型是" + a.getClass().getName);
        System.out.println("b的类型是" + b.getCass().getName());
    }
}

//实例化泛型类
public class Demo {
    public static void main(String[] args) {
        GenericDemo<String, Integer> ge1 = new GenericDemo<String, Integer>("Jack", 23);
        ge1.showType();
    }
}

输出结果:
a的类型是java.lang. String
b的类型是java.lang Integer
在示例15中,GenericDemo<T,V>类定义了两个类型参数,分别是T和V。定义时这两个类型变量的具体类型并不知道。注意,当在一个泛型中, 需要声明多个类型参数时,只需要在每个类型参数之间使用逗号将其隔开即可。在实例化泛型类时,就需要传递两个类型参数,这里分别使用了String和Integer代替了T和V。

3.从泛型类派生子类

面向对象的特性同样适用于泛型类,所以泛型类也可以继承。不过,继承了泛型类的子类,必须也是泛型类。
继承泛型类的语法格式如下。

class 子类<T> extends父类<T>{}

示例16
定义泛型父类,同时定义一个泛型子类继承泛型父类。
实现步骤如下。
(1)定义父类Fam,并添加整型字段plantNum方法、plantCrop(T crop)
(2)定义子类FruitFarm ,重写方法plantCrop(List list)
关键代码:


//父类Farm<T>(农场类)
public class Farm<T> {
    protected int plantNum = 0;//农作物种植数量

    public void plantCrop(T crop) {//种植农作物的方法
        plantNum++;
    }
}

//子类果园类继承泛型类Farm<T>
public class FruitFarm<T> extends Farm<T> {
    public void plantCrop(List<T> list) {//重写种植农作物的方法
        plantNum += list.size();

    }
}

猜你喜欢

转载自blog.csdn.net/sanjiang521/article/details/107706000