30-泛型

 

package generics;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

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

        // 创建对象
        // 不写泛型,默认为Object类型,可以存储任意类型的数据
        // 格式:集合类 对象名 = new 集合类();
        ArrayList list1 = new ArrayList();
        list1.add("abc");
        list1.add(1);
        list1.add(true);
        System.out.println(list1);

        // 迭代器不适用泛型
        System.out.println("=================迭代器遍历(不使用泛型)==================");
        Iterator it1 = list1.iterator();
        while(it1.hasNext()){
            // 取出的元素是Object类型
            Object obj = it1.next();
            System.out.println(obj);
        }


        // 泛型只能是引用类型,不能是基本类型
        // 格式:集合类<泛型> 对象名 = new 集合类<泛型>();
        ArrayList<String> list2 = new ArrayList<String>();
        list2.add("张三");
        list2.add("李四");
        list2.add("王五");
        System.out.println(list2);

        // 迭代器使用泛型
        System.out.println("=================迭代器遍历(使用泛型)==================");
        Iterator<String> it2 = list2.iterator();
        while(it2.hasNext()){
            // 取出的元素是String类型
            String s = it2.next();
            System.out.println(s);
        }
    }
}

 

 

泛型类

常见的泛型标识符:E、T、K、V

1)E:Element 元素

2)T:Type 类型

3)K:Key 键

4)V:Value 值

package generics;

/*
*  常见的泛型标识符:E、T、K、V
*  E:Element 元素
*  T:Type 类型
*  K:Key 键
*  V:Value 值
*
*  清楚不同的泛型,在什么时机确定到具体的类型
* 
*  泛型类的使用场景,创建对象的时候
*
* */

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

        Student<String> stu = new Student<>("张三", "23");
        System.out.println(stu.getName() + "," + stu.getAge());

    }
}

class Student<E>{
    private E name;
    private E age;

    public E getName() {
        return name;
    }

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

    public E getAge() {
        return age;
    }

    public void setAge(E age) {
        this.age = age;
    }

    public Student(E name, E age){
        this.name = name;
        this.age = age;
    }
}

 

泛型方法

1)非静态方法:内部的泛型,会根据类的泛型去匹配

2)静态方法:静态方法中,如果加入了泛型,必须声明出自己独立的泛型

package generics;

/*
 *  泛型方法:
 *  1. 非静态的方法:内部的逻辑,会根据类的泛型去匹配
 *  2. 静态的方法:静态方法中,如果加入了泛型,必须声明出自己独立的泛型
 *
 * */

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

            // 创建工具类对象
            Tool<String> tool = new Tool<>();
            // 非静态的方法:内部的逻辑,会根据类的泛型去匹配
            tool.show("马铃薯");

            // 静态的方法:静态方法中,如果加入了泛型,必须声明出自己独立的泛型
            String[] s = new String[]{"马铃薯", "土豆", "洋芋"};
            tool.print(s);
            // 这里注意,静态方法也可以直接用类名调用,不需要创建对象
            Tool.print(s);
    }
}

class Tool<T>{
    // 非静态的方法:内部的逻辑,会根据类的泛型去匹配
    public void show(T t){
        System.out.println(t);
    }

    // 静态方法:不会根据类的泛型去匹配,要自己声明泛型
    // 这是因为静态方法是通过类名调用的,不需要创建对象去调用方法,因此必须声明出自己独立的泛型
    public static <T> void print(String[] t){
        System.out.print("[");
        for(int i = 0; i < t.length; i++){
            if(i == t.length - 1){
                System.out.println(t[i] + "]");
            }else{
                System.out.print(t[i] + ", ");
            }
        }
    }
}

这里需要注意:泛型是对引用数据类型来讲的,因此上面的案例如果使用整型、浮点数要使用 Integer[]、Double[]

String[] s = new String[]{"马铃薯", "土豆", "洋芋"};
Integer[] i = new Integer[]{1, 2, 3};
Double[] d = new Double[]{1.1, 2.2, 3.3};

 

泛型接口

1)实现类实现接口的时候,可以指定泛型的类型

2)实现类实现接口的时候,如果没有指定泛型的类型,那么就让接口的泛型跟着类的泛型匹配

package generics;

/*
*  泛型接口:
*  1. 实现类实现接口的时候,可以指定泛型的类型
*  2. 实现类实现接口的时候,如果没有指定泛型的类型,那么就让接口的泛型跟着类的泛型匹配
*
* */

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

        // 创建工具类对象
        InterAImpl inter1 = new InterAImpl();
        inter1.show("马铃薯");

        InterBImpl<String> inter2 = new InterBImpl<>();
        inter2.show("马铃薯");
    }
}

interface Inter<E>{
    void show(E e);
}

// 实现类实现接口的时候,可以指定泛型的类型
class InterAImpl implements Inter<String>{
    @Override
    public void show(String s) {
        System.out.println(s);
    }
}

// 实现类实现接口的时候,如果没有指定泛型的类型,那么就让接口的泛型跟着类的泛型匹配
class InterBImpl<E> implements Inter<E>{
    @Override
    public void show(E e) {
        System.out.println(e);
    }
}

 

泛型通配符

1)? :代表任意的数据类型

2)? extends E:向下限定,E及其子类

3)? super E:向上限定,E及其父类

package generics;

import java.util.ArrayList;

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

        /*
        *  泛型通配符
        *  ? :代表任意的数据类型
        *  ? extends E:向下限定,E及其子类
        *  ? super E:向上限定,E及其父类
        *
        * */

        ArrayList<Coder> list1 = new ArrayList<>();
        list1.add(new Coder("张三", 10000));
        // 输出时,默认调用Objec类toString()方法
        System.out.println(list1); // [Coder{name=张三, salary=10000.0}]

        ArrayList<Manager> list2 = new ArrayList<>();
        list2.add(new Manager("李四", 20000)); // [Manager{name=李四, salary=20000.0}]
        System.out.println(list2);

        // ? :代表任意的数据类型
        method1(list1);

        // ? extends Employee:向下限定,Employee及其子类
        method2(list1);

        // ? super Coder:向上限定,Coder及其父类
        method3(list1);

    }
    // 泛型通配符
    // ?:代表任意的数据类型
    public static void method1(ArrayList<?> list){
        for(Object o:list){
            // 这里注意,o对象不能明确是什么类型,所以不能调用子类特有的方法
            // 因此通过向下转型,将o对象转换为Employee类型
            Employee e = (Employee)o;
            e.work();
        }
    }
    // ? extends E:向下限定,E及其子类
    public static void method2(ArrayList<? extends Employee> list){
        for(Object o:list){
            Employee e = (Employee)o;
            e.work();
        }
    }
    // ? super E:向上限定,E及其父类
    public static void method3(ArrayList<? super Coder> list){
        for(Object o:list){
            // 这里注意,o对象不能明确是什么类型,所以不能调用子类特有的方法
            // 因此通过向下转型,将o对象转换为Employee类型
            Coder e = (Coder)o;
            e.work();
        }
    }
}

abstract class Employee{
    private String name;
    private double salary;

    public Employee(){
        // System.out.println("父类Employee()的无参构造方法");
    }
    public Employee(String name, double salary){
        this.name = name;
        this.salary = salary;
        // System.out.println("父类Employee()的有参构造方法");
    }

    // 抽象方法
    public abstract void work();

    public String getName() {
        return name;
    }

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

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public String toString(){
        return "Employee{name=" + name + ", salary=" + salary + "}";
    }
}

class Coder extends Employee{
    public Coder(){
        // System.out.println("子类Coder()的无参构造方法");
    }
    public Coder(String name, double salary){
        super(name, salary);
        // System.out.println("子类Coder()的有参构造方法");
    }

    @Override
    public String toString(){
        return "Coder{name=" + getName() + ", salary=" + getSalary() + "}";
    }

    public void work(){
        System.out.println("程序员敲代码...");
    }
}

class Manager extends Employee{

    public Manager(){
        // System.out.println("子类Manager()的无参构造方法");
    }
    public Manager(String name, double salary){
        super(name, salary);
        // System.out.println("子类Manager()的有参构造方法");
    }

    @Override
    public String toString(){
        return "Manager{name=" + getName() + ", salary=" + getSalary() + "}";
    }

    public void work(){
        System.out.println("项目经理分配任务...");
    }
}

 

 

posted @ 2024-01-27 10:52  马铃薯1  阅读(2)  评论(0编辑  收藏  举报