0
点赞
收藏
分享

微信扫一扫

java基础-day13-泛型

承蒙不弃 2021-09-29 阅读 64

泛型

1. 泛型

1.1 为什么要使用泛型
1. 泛型能够让代码更加具有普适性!!!
    例如昨天的排序算法,目前支持的有且只有Worker数据类型
    后期开发中,一定会涉及到很多种数据类型的排序,排序算法是一致的,不同的是排序规则,和排序处理的数据类型
    可以使用泛型来对数据类型进行更高层级的处理

2. 泛型可以减少没有必要的强制类型转换!!!
3. 泛型可以在满足数据类型多样化的情况下,通过一定的条件约束,能够做到足够的数据类型一致化要求。
1.2 泛型的基本格式
格式:
    <T> <E> <K> <V>
    <自定义无意义单个大写英文字母泛型占位符>

可以使用的地方
    1. 方法
    2. 类
    3. 接口

1.3 泛型在方法中使用

方法内使用自定义声明泛型
    【强制要求】
        方法使用的泛型,一定需要在参数中存在,用于约束当前方法使用的泛型占位符具
        体数据类型是哪一个
package com.qfedu.a;

public class Demo1 {
    public static void main(String[] args) {
        String str = testType("字符串");
        Integer i = testType(1);
        Demo1 d1 = testType(new Demo1());
        
    }
    
    /**
     * 带有自定义泛型<T>的方法,需要的参数和返回值类型都是泛型T
     * 【重点】 泛型的具体数据类型是需要通过实际参数来约束的
     * 
     * @param <T> 自定义泛型单个大写英文字母无意义占位符
     * @param t 用户指定的数据类型,第一个是一个参数,第二用于约束T对应的具体数据类型
     * @return 自定义泛型T 被约束之后的具体数据类型
     */
    public static <T> T testType(T t) {
        System.out.println(t.getClass());
        return t;
    }

}
package com.qfedu.a;

public class Demo2 {
    
    public static void main(String[] args) {
        /*
         * int 和 Integer 之间的关系
         * Integer 这是一个类 是 int 数据类型的包装类
         * 
         * int 和 Integer可以无缝衔接,但是有一些不同之处。
         */
        Integer[] arr = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
        
        printArray(arr);
        
        String[] strArr = {"七一建党", "八一建军", "十一国庆", "五一劳动", "六一儿童"};
        
        printArray(strArr);
    }
    
    public static <T> void printArray(T[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}
1.3 泛型在类内的使用
格式:
    class 类名<自定义无意义单个大写字母占位符> {
        类内的非静态成员方法可以使用自定义泛型
    }
package com.qfedu.a;

/**
 * 当前类带有自定义泛型
 *      当前自定义泛型可以在类内的方法使用
 * @author Anonymous
 *
 * @param <T>
 */
class TypeR<T> {
    public void test(T t) {
        System.out.println(t);
    } 
    
    public T getType(T t) {
        return t;
    }
    
    /*
     * 静态方法是否可以使用类名声明的泛型
     * 
     * 静态成员方法在类文件的加载阶段需要明确所有的内容。
     * 
     * 类名声明的自定义泛型占位符是在创建类对象时,明确当前泛型
     * 对应的具体数据类型是什么。
     * 静态成员方法在类文件加载之后,已经可以通过类名直接调用。
     * 
     * 生命周期存在一定的时间差!!!
     * 
     */
    // public static T testStatic(T t) {    
    // }
    
    /* 
     * 自娱自乐
     * 
     * 通常情况下,静态方法自定义泛型会考虑和类名声明泛型不冲突!!!
     */
    public static <E> E testStatic(E e) {
        return e;
    }

}

public class Demo3 {
    public static void main(String[] args) {
        /*
         * 创建一个带有自定义泛型的类对象,格式如下
         * Eclipse中:
         *      TypeR<String> typeR = new TypeR<String>();
         * IDEA 
         *      TypeR<String> typeR = new TypeR<>();
         * 
         * 明确告知编译器,当前类对象typeR 自定义泛型对应的具体数据类型为String类型
         */
        TypeR<String> typeR = new TypeR<String>();
        // 类内所有使用到自定义泛型的位置都是String
        typeR.test("测试");
        String str = typeR.getType("大家注意身体");
        
        // 当前约束之后,方法内所有使用到泛型的位置,都是Integer类型
        TypeR<Integer> typeR2 = new TypeR<Integer>();
        typeR2.test(10);
        Integer type = typeR2.getType(10);
        
        TypeR typeR3 = new TypeR();
        /*
         *  数据类型一致化!!!
         *  
         *  一个类带有自定义泛型,在创建对象的过程中,没有约束泛型的具体数据类型,泛型         *  对应的所有类型都是Object类型
         *  这样做有悖于泛型的使用要求,泛型使用是为了 提供代码的普适性,可变通性,但
         *  是不能违背数据类型一致化要求。
         */
        typeR3.test('六');
        typeR3.test("就是这么牛");
        typeR3.test(new Demo1());
    }
}
1.4 泛型在接口中使用
格式:
    interface 接口名<自定义泛型占位符> {
        成员变量不得使用自定义泛型数据类型
            接口中成员变量缺省属性为public static final 
            final修饰的成员变量,定义时必须初始化,在泛型没有明确数据类型之前,
            无法针对当前数据类型进行合理的初始化操作。【不能使用】
        
        接口中的方法可以使用自定义泛型
            缺省属性方法
            default默认方法
    }
package com.qfedu.a;

interface A<T> {
    /**
     * 类内的缺省属性为public abstract方法,当前方法的返回值和参数类型
     * 都使用了自定义泛型
     * 
     * @param t 接口自定义的泛型数据类型 
     * @return 接口自定义的泛型数据类型
     */
    T testA(T t);
    
    /**
     * 默认方法,default修饰方法,当前方法可以拥有方法体,该方法的返回值
     * 和参数类型都是接口自定义泛型。
     * 
     * @param t 接口自定义的泛型数据类型
     * @return 接口自定义的泛型数据类型
     */
    default public T testDefault(T t) {
        return t;
    }
}

/*
 * 自由 Freedom
 * 
 * 类名声明和实现接口一致的泛型使用,泛型对应的具体数据类型是依赖于
 * 创建当前类对象时进行数据约束的。
 */
class TypeFreeDom<T> implements A<T> {

    @Override
    public T testA(T t) {
        System.out.println(t.getClass());
        return t;
    }

}

/*
 * 妻管严模式
 * 
 * 遵从接口的过程中,已经明确当前泛型对应的具体数据类型是什么'
 * 接下来所有接口中使用到泛型的方法,都是有接口之后的数据类型进行
 * 约束。
 */
class QFY implements A<String> {

    @Override
    public String testA(String t) {
        // TODO Auto-generated method stub
        return null;
    }
    
}

public class Demo4 {
    public static void main(String[] args) {
        TypeFreeDom<String> tf = new TypeFreeDom<String>();
        
        String testA = tf.testA("测试呢");
        String testDefault = tf.testDefault("测试默认方法");
        
        TypeFreeDom<Character> tf2 = new TypeFreeDom<Character>();
        
        tf2.testA('A');
        tf2.testDefault('A');
        
        new QFY().testA("围城");
        new QFY().testDefault("城堡");
    }
}
举报

相关推荐

Day13-日历模块

day13-面向对象3

day13-算法每日4题

java基础-泛型

Java基础【泛型】

Java基础_泛型

java基础 --泛型

0 条评论