09_面向对象高级_泛型

泛型

1. 认识泛型

定义类、接口、方法时,同时声明了一个或多个类型变量(如:),称为泛型类、泛型接口、泛型方法、它们统称为泛型。

2. 泛型类
public class Test {
    public static void main(String[] args) {
        MyArrayList<String> list = new MyArrayList<>();
        System.out.println(list.add("Jack"));  // true
        System.out.println(list.get(0));  // Jack
    }
}

// 自定义一个泛型类,去模拟 ArrayList
class MyArrayList<E> {  // 如果不想规范地写,其实E也可以写成其他字母
    private Object[] arr = new Object[10];  // 容器,用来装东西
    private int size;  // 记录当前装了多少个

    public boolean add(E content) {
        arr[size++] = content;
        return true;
    }

    public E get(int index) {
        return (E) arr[index];
    }
}
public class Test {
    public static void main(String[] args) {
        MyClass<String, String> obj = new MyClass<>();
        obj.put("只能是String类型", "只能是String类型");
//      Others obj1 = new Others<>();  // 报错
        Others<MyClass> obj2 = new Others<>();  // 正常
        System.out.println(obj2.age);  // 输出结果:0

    }
}

class MyClass<E, T> {
    public void put(E e, T t) {

    }
}

// 要求 E 的类型是继承 MyClass 或者 E 的类型是 MyClass
class Others<E extends MyClass> {
    public int age;
}
3. 泛型接口
  • 注意:类型变量建议用大写的英文字母,常用的有:E、T、K、V 等
import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {

    }
}

class Student {

}

class Teacher {

}

// 泛型接口
interface Data<E> {
    void add(E obj);

    ArrayList<E> getByName(String name);

}

// 实现类
class StudentData implements Data<Student> {

    @Override
    public void add(Student obj) {

    }

    @Override
    public ArrayList<Student> getByName(String name) {
        return null;
    }
}

// 实现类
class TeacherData implements Data<Teacher> {

    @Override
    public void add(Teacher obj) {

    }

    @Override
    public ArrayList<Teacher> getByName(String name) {
        return null;
    }
}
4. 泛型方法

案例一

public class Test {
    public static void main(String[] args) {
        System.out.println(get(10));  // 10
        System.out.println(get("Java"));  // Java
        System.out.println(get(new A()));  // 对象的内存地址: login.A@3b07d329
    }

    // 泛型方法
    public static <T> T get(T name) {
        return (T) name;
    }

    // 泛型方法
    public static <E> void run(E index) {

    }
}

class A {

}

案例二

通配符:就是" ? ",可以在"使用泛型"的时候代表一切类型;E T K V 是在定义泛型的时候使用

import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {
        // 需求:实现所有的汽车都能一起参加比赛
        ArrayList<Car> cars = new ArrayList<>();
        cars.add(new BMW());
        cars.add(new BENZ());
        go(cars);

        ArrayList<BMW> bmws = new ArrayList<>();
        bmws.add(new BMW());
        bmws.add(new BMW());
        go(bmws);

        ArrayList<BENZ> benzs = new ArrayList<>();
        benzs.add(new BENZ());
        benzs.add(new BENZ());
        go(benzs);

        ArrayList<Dog> dogs = new ArrayList<>();
        dogs.add(new Dog());
        dogs.add(new Dog());
//      go(dogs);  // 报错

    }

    // 是没有限制数据类型的泛型,如果我们加一个限制条件,不要让狗类进来,可以这样写:,完整代码如下一行所示
    public static <T extends Car> void go(ArrayList<T> allCars) {

    }

    // 知识扩展:
    // ? 是通配符,在使用泛型的时候可以代表一切类型" ? extends Car "【上限】  " ? super Car "【下限】
//    public static void go1(ArrayList allCars) {}
//    public static void go2(ArrayList allCars) {}
}

class Car {

}

class BMW extends Car {

}

class BENZ extends Car {

}

class Dog {

}
5. 注意事项
  • 泛型是工作在编译阶段的,一旦程序编译成 class 文件,class 文件中就不存在泛型了,这就是泛型擦除。
  • 泛型不支持基本数据类型,只能支持对象类型(引用数据类型)
import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {
//      ArrayList list1 = new ArrayList<>();  // 报错
        ArrayList<Integer> list2 = new ArrayList<>();  // 正常
    }
}

你可能感兴趣的:(Java进阶,java)