Java_自定义泛型类/接口/方法
自定义泛型类:
基本语法:
class 类名 <T,R.....>{ //也可以是接口 , ........表示可以有多个泛型
成员
}
注意:
1)普通成员可以使用泛型(属性,方法)
2)使用泛型的数组,不能初始化
3)静态方法(属性)中不能使用类的泛型
4)泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定确定类型)
5)如果在创建对象时,没有指定类型,默认为Object
package com.genericStu.customGeneric;public class CustomGeneric_ {public static void main(String[] args) {}
}
//解读:
//1.Tiger后面有泛型,所以我们把Tiger 称为自定义泛型类
//2.T,R,M 称为泛型的标识符,一般是单个的大写字母
//3.泛型的标识符可以有多个
//4.普通成员可以使用泛型(属性,方法)
//5.使用泛型的数组,不能初始化
class Tiger<T,R,M>{String name;R r;//属性 使用到了泛型M m;T t;//使用泛型的数组,不能初始化//T[] ts = new T[8]; 因为数组在new 的时候不能确定 T的类型,就无法在内存开空间T ts[];public Tiger(String name, R r, M m, T t) { //构造器使用泛型this.name = name;this.r = r;this.m = m;this.t = t;}public R getR() { //返回类型使用到泛型return r;}public void setR(R r) { //方法使用到泛型this.r = r;}//静态方法/属性中不能使用类的泛型//public static void m1(M m){}//static R r2;//因为静态是和类相关的,在类加载时,对象还没有创建//所以,如果静态方法和静态属性使用了泛型,JVM就无法初始化
}自定义泛型接口:
基本语法:
interface 接口名<T,R.......>{
}
注意:
1)接口中,静态成员也不能使用泛型(这个和泛型类规定一样)
2)泛型接口的类型,在继承接口或实现接口时确定
3)没有指定类型,默认为Object
package com.genericStu.customGeneric;public class CustomInterfaceGeneric {public static void main(String[] args) {}
}
interface IUsb<U,R>{//普通方法中,可以使用接口泛型R get(U u);void hi(R r);void run(R r1,R r2,U u1,U u2);int n = 10;//U name; 在接口中属性都是静态的 static final//在jdk8中,可以在接口中,使用默认方法default R method(U u){return null;}
}
//没有指定类型时默认为Object
//建议直接写成class C implements IUsb<Object,Object>
class C implements IUsb{ //等价于class C implements IUsb<Object,Object>@Overridepublic Object get(Object o) {return null;}@Overridepublic void hi(Object o) {}@Overridepublic void run(Object r1, Object r2, Object u1, Object u2) {}@Overridepublic Object method(Object o) {return IUsb.super.method(o);}
}//实现接口时,直接指定泛型接口的类型
//给U 指定Integer ,给R指定float
//所以,当我们实现IUsb方法时,会使用Integer替换U,使用float替换R
class BB implements IUsb<Integer,Float>{@Overridepublic Float get(Integer integer) {return null;}@Overridepublic void hi(Float aFloat) {}@Overridepublic void run(Float r1, Float r2, Integer u1, Integer u2) {}@Overridepublic Float method(Integer integer) {return IUsb.super.method(integer);}
}//继承接口
interface IA extends IUsb<String,Integer>{}
//当实现IA接口时,因为IA在继承IUsb接口时,指定了 U为String ,R为Double
//在实现IUsb接口时,使用String替换U,使用double替换R
//idea快捷键 ctrl + i 自动实现
class D implements IA{@Overridepublic Integer get(String s) {return null;}@Overridepublic void hi(Integer integer) {}@Overridepublic void run(Integer r1, Integer r2, String u1, String u2) {}@Overridepublic Integer method(String s) {return IA.super.method(s);}
}自定义泛型方法:
基本语法:
修饰符<T,R......> 返回类型 方法名(形参列表){
}
注意:
1)泛型方法,可以定义在普通类中,也可以定义在泛型类中
2)当泛型方法被调用时,类型会确定
3)public void eat(E e){ } 修饰符后没有<T,R......> 则eat() 不是泛型方法,而是使用了泛型
package com.genericStu.customGeneric;import java.util.ArrayList;public class CustomMethodGeneric {public static void main(String[] args) {Car car = new Car();//调用泛型方法直接传值即可,传入参数后编译器就会确定类型,这里的100会被自动装箱变为Integercar.fly("泥嚎",100);car.fly(300,120);//测试//T就是String ,R就是ArrayListFish<String, ArrayList> fish = new Fish<>();fish.hello(new ArrayList(),11.3f);}
}
//泛型方法,可以定义在普通类中,也可以定义在泛型类中
class Car{ //普通类public void run(){}//普通方法//T,R就是泛型标识符,是提供给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){ //泛型方法}//下面这个方法不是泛型方法,是hi() 使用了类声明的泛型public void hi(T t,R r){}//泛型方法,可以使用类声明的泛型,也可以自己声明泛型public<K> void hello(R r,K k){System.out.println(r.getClass());System.out.println(k.getClass());}
}