本次博客带领大家学习自定义泛型,了解自定义泛型类、接口和方法等等。
class 类名<T,R...>{//...表示可以有多个泛型
成员
}
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...>{
}
//在继承接口 指定泛型接口的类型
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
class CC implements IUsb{//等价于class CC implements IUsb
@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...>返回类型 方法名(参数列表){
}
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. 这个就是泛型
//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{}