欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 泛型 类 接口 方法 通配符

泛型 类 接口 方法 通配符

2025/2/26 0:37:16 来源:https://blog.csdn.net/qq_36545519/article/details/145622004  浏览:    关键词:泛型 类 接口 方法 通配符

泛型

泛型类

what:

类型参数化

why use:

1. 输出时候是object类型 而不是真正类型转化麻烦
import java.util.ArrayList;
import java.util.List;public class ObjectExample {public static void main(String[] args) {List<Object> list = new ArrayList<>();list.add("Hello");list.add(123); // 可以添加任何类型的对象// 运行时可能会出现 ClassCastExceptionString str = (String) list.get(1); System.out.println(str);}
}

一个盒子 什么类型都可以装

而不是 橘子 苹果 火龙果盒子

分别对应一个类

fault example:

package box;import fruit.*;public class box {
}public class appleBox{private apple apple;private double length;private double width;private double heigth;private double count;private double weigth;appleBox(){}appleBox(apple apple,double length,double width,double heigth,double count,double weigth){this.apple = apple;this.length = length;this.width = width;this.heigth = heigth;this.count = count;this.weigth = weigth;}public class orangeBox{private orange orange;private double length;private double width;private double heigth;private double count;private double weigth;orangeBox(){}orangeBox(orange orange, double length, double width, double heigth, double count, double weigth){this.orange = orange;this.length = length;this.width = width;this.heigth = heigth;this.count = count;this.weigth = weigth;}public class pitayaBox{private pitaya pitaya;private double length;private double width;private double heigth;private double count;private double weigth;pitayaBox(){}pitayaBox(pitaya pitaya,double length,double width,double heigth,double count,double weigth){this.pitaya = pitaya;this.length = length;this.width = width;this.heigth = heigth;this.count = count;this.weigth = weigth;}}
  • 代码冗余:每个盒子类的逻辑几乎相同,只是类型不同,但需要重复编写。
  • 扩展性差:如果需要支持更多类型的水果,就需要继续添加更多的盒子类。
  • 维护困难:如果需要修改盒子的功能(如增加新的方法),需要在每个盒子类中逐一修改。

example:

bug1:构造函数不公开化 外部无法构造
/*构造函数公开化*/public boxGeneric(T fruit, double length, double width, double heigth, double count, double weigth) {this.fruit = fruit;this.length = length;this.width = width;this.heigth = heigth;this.count = count;this.weigth = weigth;}
泛型实例:
package box;/*
what:generic 类型参数化*/
public class boxGeneric<T> {/*what:不同部分只是水果类型 给他类型参数化但是我接收时候只能接收一种水果类型 然后对应对象确定了 是 苹果盒子/橘子盒子 然后就当苹果盒子正常使用*/private T fruit;private double length;private double width;private double heigth;private double count;private double weigth;/*构造函数公开化*/public boxGeneric(T fruit, double length, double width, double heigth, double count, double weigth) {this.fruit = fruit;this.length = length;this.width = width;this.heigth = heigth;this.count = count;this.weigth = weigth;}public T getFruit() {return fruit;}public void setFruit(T fruit) {this.fruit = fruit;}public double getLength() {return length;}public void setLength(double length) {this.length = length;}public double getWidth() {return width;}public void setWidth(double width) {this.width = width;}public double getHeigth() {return heigth;}public void setHeigth(double heigth) {this.heigth = heigth;}public double getCount() {return count;}public void setCount(double count) {this.count = count;}public double getWeigth() {return weigth;}public void setWeigth(double weigth) {this.weigth = weigth;}
}
调用:
import box.boxGeneric;
import fruit.apple;public class Main {public static void main(String[] args) {/*使用泛型水果盒子*/apple apple = new apple();boxGeneric<fruit.apple> appleboxGeneric = new boxGeneric<>(apple, 1, 1, 1, 1, 1);System.out.println(appleboxGeneric.getFruit().getName());}}
apple类型
package fruit;public class apple {private final String name = "apple";public String getName() {return name;}
}
语法

创建 参数化类

class boxGeneric<T>(T fruit){T fruit;}

创建泛型对象

new boxGeneric<>()alt + enter

image-20250206145118086

接口使用

接口后要立马接收参数 类型参数

类后要立马接收参数 类型参数

接口

package interfaceModle;
/*
what:接口使用泛型 参数要紧紧跟着类呀*/
public interface keyInterface<T> {/*接口函数返回类型为泛型*/T getKey();
}

使用1:实现泛型接口的类 不是泛型类 实现类不用接收参数类型 接口还要由实现类给出参数 那么 我们自己指定接口的类型参数

这时实现类使用接口时候 要给出接口的类型参数 因为外部无法给出参数类型 只能我自己给,如果实现类 不给接口参数 默认给接口Object类型

package imple;import interfaceModle.keyInterface;
/*
非泛型类 要给接口类型参数*/
public class keyImple implements keyInterface<String> {@Overridepublic String getKey() {return "This is a key ------ 并非generic 是由实现类直接指定类型";}
}
main:
/*what:实现类直接指定类型 的 实现类返回信息*/public static void test2(){keyImple keyImple = new keyImple();System.out.println(keyImple.getKey());}

使用2:实现类接收外部的类型参数 接口泛型参数由实现类给出 则接口的类型参数 可以与实现类参数一致 ,也可以直接由实现类给出

package imple;import interfaceModle.keyInterface;/*
what:实现类接收类型参数 赋值给接口参数*/
public class keyGenericImple<T,E> implements keyInterface<T> {private T key;private E value;public keyGenericImple(T key, E value) {this.key = key;this.value = value;}public E getValue() {return value;}public void setValue(E value) {this.value = value;}@Overridepublic T getKey() {return key;}public void setKey(T key) {this.key = key;}
}
main
/*what:实现类接收类型参数 发给接口的类型参数确定类型参数 设置普通参数值 返回信息*/public static void test3(){keyGenericImple<String, Integer> si = new keyGenericImple<>("你好", 114514);String key = si.getKey();Integer value = si.getValue();System.out.println(key + " = " + value);}

方法使用

在调用方法时候指明泛型的具体类型

泛型类 作用在 返回值 参数上 但 方法内部无法使用泛型

即 泛型类只在类内部使用 方法内部使用泛型需要泛型方法

how use:

  • 泛型类后面紧接所需要的参数
  • 泛型方法后面无需紧跟参数 但是 泛型方法需要被修饰所以泛型标志在函数名前面
  • 能用泛型方法里的泛型E,类的泛型T也可以用

how set parameter:

类的传递参数写在类的后面

getProduct<Integer> gp = new getProduct<>();

接口的类型参数写作接口后面


方法的类型参数写在 修饰符那里


泛型方法的类型参数 只能通过接收参数时候设置 方法泛型类型 其他没地方接收类型参数呀。。。。

example:

类管类的内部 方法管方法的内部及 方法返回值 方法参数

方法和类 同一个类型参数T 时候 设置一个T = 方法和类全部设置

泛型类 + 泛型方法设置参数

泛型方法

package methodGeneric;import java.util.ArrayList;
import java.util.Random;/*
what:给出任意类型列表 返回一个奖品*/
public class getProduct<E> {/*what:方法接收任意类型集合 返回一个奖品how use:方法类型参数 修饰作用 所以在最前面 声明后 该方法返回值 形式参数都可以使用该类型接收任意类型奖品列表how set type parameter:1.接收参数时候设置参数中的类型参数时 设置方法类型的参数*/Random rand = new Random();public <T> T getProductMethod(ArrayList<T> list) {return list.get(rand.nextInt(list.size()));}
}

传入泛型类 类型参数(类后面直接给出) 、泛型方法类型参数(方法参数设置参数)

/*
what:给出字符串类型奖品列表 返回奖品*/public static void test4(){ArrayList<String> list = new ArrayList<>();list.add("笔记本电脑");list.add("苹果手机");list.add("安卓手机");/*what:传给方法 抽出奖品*/getProduct<Integer> gP = new getProduct<>();String product = gP.getProductMethod(list);System.out.println("取出奖品为:" + product);
}/*
what:给出数字类型列表 抽出奖金*/
public static void test5(){ArrayList<Integer> products = new ArrayList<>();products.add(1000);products.add(20000);products.add(300000);getProduct<Integer> gP = new getProduct<>();Integer product = gP.getProductMethod(products);System.out.println("你的奖金为:" + product);
}
careout:
  • 设置类泛型参数后 不一定设置方法的类型参数
  • 类和方法类型参数名字就算一样 也是相互独立的
  • 类的类型参数在实例化对象时设置
  • 方法类型参数在接收 形式参数时设置

泛型类设置类型参数–成员方法 仅泛型类类型参数接收

泛型方法 任意类型参数接收

泛型类的成员方法 无法静态

泛型方法 可以静态 泛型方法不是泛型类的成员方法

泛型成员方法:
{getProduct<Integer> gP = new getProduct<>();/*what;数组*/int[] arr = {1000,20000,3000000};ArrayList<Integer> products = new ArrayList<>();for(int i = 0;i<arr.length;i++){products.add(arr[i]);}/*what:泛型实例化 给成员方法得到奖品*/getProduct<Integer> gp = new getProduct<>();Integer product0 = gp.getProduct0(products);System.out.println(product0 + " " + product0.getClass().getName());}
public class getProduct<E> {Random rand = new Random();/*what:泛型类的成员方法  成员方法全部依赖泛型类 比如 泛型类的类型参数返回奖品*/public E getProduct0(ArrayList<E> list) {return list.get(rand.nextInt(list.size()));}}
泛型方法;
public <T, E, K, V> void getMessage(T t,E e,K k,V v){System.out.println(t + "\t" + t.getClass().getName());System.out.println(e + " \t" + t.getClass().getName());System.out.println(k + " \t" + k.getClass().getName());System.out.println(v + " \t" + v.getClass().getName());}
public static void test7(){getProduct<Integer> gp = new getProduct<>();gp.getMessage("aaa","bbb",false,true);System.out.println("------------");gp.getMessage(true,false,1,22.66);}

泛型可变参数

泛型方法上E… e 泛型方法前设置修饰符

public static <E> void constantParameterPrint(E... e){for(int i = 0;i<e.length;i++){System.out.println(e[i]);}}
public static void test7(){getProduct<Integer> gp = new getProduct<>();gp.getMessage("aaa","bbb",false,true);System.out.println("------------");gp.getMessage(true,false,1,22.66);System.out.println("------------");gp.constantParameterPrint(1,2,3,4,5);System.out.println("------------");gp.constantParameterPrint('a','b','c','d','e');}

类型通配符

difficult:

1.Box box 这是一个Box对象 指明Box对象形式参数 创建Box实例对象 而不是一个列表 ArrayLIst arrayList 创建一个ArrayList对象 指明 Number参数 创建arrayList 实例对象

why use:

​ 在用泛型对象作为参数时候 相当于实例化对象 这时候要给对象泛型类型发参数,说明函数有泛型类 实例化对象时 我们已经给该泛型 实例化对象设置了 泛型的类型 这时候 多种类型传入函数(泛型类 实例化对象已经指定) 这时候就会报错

interge 与 Number 在泛型类型参数里不能当作 父亲接收子 多态来理解

solve:

  • 方法重载?
    • 同名 不能形式参数 尽管泛型的接收类型参数不一样 但是他们都是泛型类 所以相同的参数 无法重载
  • Object 泛型类类型参数
    • 那么不利于上层接收调用 以为是Object类型

在函数形式参数 泛型类实例化对象 用问号代替类型参数 该泛型类接收所有类型的类型参数 然后实例化形式参数

example:

package typeWildcard;public class test {/*what:模拟多次 不同类型的泛型对象传入含有通配符函数返回Object类型 但是上一层强转类型即可*/public static void main(String[] args) {Box<Number> box1 = new Box<>();box1.setFirst(1);Number o = (Number)showBox(box1);System.out.println(o);System.out.println("-------------");Box<String> box2 = new Box<>();box2.setFirst("函数的形式参数 实例化 接收全部类型");String s = (String)showBox(box2);System.out.println(s);}/*what;函数的形式参数 实例化也需要指定泛型类的类型参数  这样无法多态public static void showBox(Box<Number> box){Number first = box.getFirst();}what effect:衬托无法多态  因为 形式参数 的类型都是泛型类 所以无法多态public static void showBox(Box<Integer> box){Number first = box.getFirst();}*//*what:1.对于函数形式参数为泛型类需要指明类型参数情况 使用问号 代表实例化时接收各种类型参数2.咱们使用Object接收 但是直接返回上一层因为上一层知道这个object是声明类型呀!!!*/public static Object showBox(Box<?> box){return box.getFirst();}}~~~java
package typeWildcard;/*
what:泛型类 当个函数形式参数实例化参数时候 必须要指定泛型类型参数*/
public class Box<T> {T first;public T getFirst() {return first;}public void setFirst(T first) {this.first = first;}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词