自定义泛型

本次博客带领大家学习自定义泛型,了解自定义泛型类、接口和方法等等。

自定义泛型类

  • 基本语法
class 类名<T,R...>{//...表示可以有多个泛型
    成员
}
  • 注意细节
    1. 普通成员可以使用泛型(属性、方法)。
    2. 使用泛型的数组,不能初始化。
    3. 静态方法中不能使用类的泛型。
    4. 泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定确定类型)。
    5. 如果在创建对象时,没有指定类型,默认为Object。
class Tiger<T,R,M>{
    String name;
    R r;
    M m;
    T t;
    //因为数组在new 不能确定T的类型,就无法在内存开空间
    T[] ys ;

    public Tiger(String name, R r, M m, T t) { //构造器使用泛型
        this.name = name;
        this.r = r;
        this.m = m;
        this.t = t;
    }
    
    //因为静态是和类相关的,在类加载加载时,对象还没有创建
    //所有,如果静态方法和静态属性使用了泛型,JVM就无法完成初始化
    static R r2;
    public static void m1(M m){
        
    }

    public String getName() {
        return name;
    }

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

    public R getR() {
        return r;
    }

    public void setR(R r) { //方法使用到泛型
        this.r = r;
    }

    public M getM() {
        return m;
    }

    public void setM(M m) {
        this.m = m;
    }

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}
//T=Double,R=String ,M=Integer
Tiger<Double, String, Integer> g = new Tiger<>("john");
g.setT(10.9);//OK
//g.setT("yy");//错误,类型不对
System.out.println(g);
Tiger g2  = new Tiger("john~~~");//OK  T=Object R=Object M=Object
g2.setT("yy");//OK,因为T=Object "yy"=String 是Object子类。
System.out.println("g2="+g2);

自定义泛型接口

  • 基本语法:
interface 接口名<T,R...>{
}
  • 注意细节
    1. 接口中,静态成员也不能使用泛型(这个和泛型类规定一样)。
    2. 泛型接口的类型,在继承接口或者实现接口时确定。
    3. 没有指定类型,默认为Object。
//在继承接口 指定泛型接口的类型
interface IA extends IUsb<String,Double>{

}
//当我们去实现IA接口时,因为IA在继承IUsb 接口时,指定了U 为String R为Double
//在实现IUsb接口的方法时,使用String替换U,Double 替换R
class AA implements IA{

    @Override
    public Double get(String s) {
        return null;
    }

    @Override
    public void hi(Double aDouble) {

    }

    @Override
    public void run(Double r1, Double r2, String u1, String u2) {

    }
}

//实现接口时,直接指定泛型接口的类型
//给U指定Integer 给R指定了Float
//所以,当我们实现IUsb方法时,会使用Integer替换 U, Float替换R
class BB implements IUsb<Integer,Float>{

    @Override
    public Float get(Integer integer) {
        return null;
    }

    @Override
    public void hi(Float aFloat) {

    }

    @Override
    public void run(Float r1, Float r2, Integer u1, Integer u2) {

    }
}

//没有指定类型,默认为Object。
//建议直接写成class CC implements IUsb<Object,Object>
class CC implements IUsb{//等价于class CC implements IUsb<Object,Object>
    @Override
    public Object get(Object o) {
        return null;
    }

    @Override
    public void hi(Object o) {

    }

    @Override
    public void run(Object r1, Object r2, Object u1, Object u2) {

    }

}

interface IUsb<U,R>{

    int n = 10;
   // U name; 接口中的属性是静态属性

    //普通方法中,可以使用接口泛型
    R get(U u);

    void hi(R r);

    void run(R r1,R r2,U u1,U u2);

    //在jdk8中,可以在接口中,使用默认方法
    default R method(U u){
        return null;
    }
}

自定义泛型方法

  • 基本语法
修饰符 <T,R...>返回类型 方法名(参数列表){
}
  • 注意细节
    1. 泛型方法,可以定义在普通类中,也可以定义在泛型类中。
    2. 当泛型方法被调用时,类型会确定。
    3. public void eat(E e){},修饰符后没有<T,R…> eat方法不是泛型方法,而是使用了泛型。
public class CustomMethodGeneric {
    public static void main(String[] args) {
        Car car = new Car();
        car.fly("宝马",100);//当调用方法时,传入参数,编译器,就会确定类型。
        System.out.println("=======");
        car.fly(300,100.1);

        //T -->String R--->ArrayList
        Fish<String, ArrayList> fish = new Fish<>();
        fish.hello(new ArrayList(),11.1);
    }
}
//泛型方法,可以定义在普通类中,也可以定义在泛型类中。
class Car{ //普通类
    public void run(){ //普通方法

    }
    //说明 泛型方法
    //1.<T,R> 这个就是泛型
    //2.是提供给 fly使用的
    public<T,R> void fly(T t,R r){//泛型方法
        System.out.println(t.getClass());
        System.out.println(r.getClass());
    }
}

class Fish<T,R>{ //泛型类
    public void run(){ //普通方法
    }
    public<U,M> void eat(U u,M m){//泛型方法

    }
    //1.下面hi方法不是泛型方法。
    //2.是hi方法使用了类声明的泛型
    public void hi(T t){
    }
    //泛型方法,可以使用类声明的泛型,也可以使用自己声明泛型
    public<K> void hello(R r,K k){
        System.out.println(r.getClass());
        System.out.println(k.getClass());
    }
}

自定义泛型练习

  • 下面代码是否正确,如果有错误,修改正确,并说明输出什么?
class Apple<T,R,M>{
    public<E> void fly(E e){
        System.out.println(e.getClass().getSimpleName());
    }
    public void eat(U u){}
    public void run(M m){}
}
class Dog{}

//下面代码输出什么?
Apple<String,Integer,Double> apple = new Apple<>();
apple.fly(10);
apple.fly(new Dog());
public class CustomMethodGenericExercise {
    public static void main(String[] args) {
        Apple<String,Integer,Double> apple = new Apple<>();
        apple.fly(10);//10 会被自动装箱 Integer10,输出Integer
        apple.fly(new Dog());//Dog
    }
}
class Apple<T,R,M>{//自定义泛型类
    public<E> void fly(E e){//泛型方法
        System.out.println(e.getClass().getSimpleName());
    }
    //public void eat(U u){}//错误,因为U没有声明
    public void run(M m){}//ok
}
class Dog{}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值