泛型 类 接口 方法 通配符

news2025/2/20 19:10:49

泛型

泛型类

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); // 可以添加任何类型的对象

        // 运行时可能会出现 ClassCastException
        String 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> {


    @Override
    public 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;
    }

    @Override
    public 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;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2297877.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文字转语音(三)FreeTTS实现

项目中有相关的功能&#xff0c;就简单研究了一下。 说明 FreeTTS 是一个基于 Java 的开源文本转语音&#xff08;TTS&#xff09;引擎&#xff0c;旨在将文字内容转换为自然语音输出。 FreeTTS 适合对 英文语音质量要求低、预算有限且需要离线运行 的场景&#xff0c;但若需…

STM32 RTC 实时时钟说明

目录 背景 RTC(实时时钟)和后备寄存器 32.768HZ 如何产生1S定时 RTC配置程序 第一次上电RTC配置 第1步、启用备用寄存器外设时钟和PWR外设时钟 第2步、使能RTC和备份寄存器访问 第3步、备份寄存器初始化 第4步、开启LSE 第5步、等待LSE启动后稳定状态 第6步、配置LSE为…

Open-R1 项目代码文件的详细剖析

目录 1. configs.py 功能概述 关键代码与细节 2. evaluate.py 功能概述 关键代码与细节 3. generate.py 功能概述 关键代码与细节 4. grpo.py 功能概述 关键代码与细节 5. rewards.py 功能概述 关键代码与细节 6. sft.py 功能概述 关键代码与细节 安装 训练…

Android RenderEffect对Bitmap高斯模糊(毛玻璃),Kotlin(1)

Android RenderEffect对Bitmap高斯模糊(毛玻璃)&#xff0c;Kotlin&#xff08;1&#xff09; import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.HardwareRenderer import android.graphics.PixelFormat import android.graphic…

区块链+隐私计算:长安链多方计算合约标准协议(CMMPC-1)发布

建设背景 长安链与隐私计算的深度融合是构建分布式数据与价值流通网络的关键基石&#xff0c;可以在有效连接多元参与主体的同时确保数据的分布式、可追溯、可计算&#xff0c;以及隐私性与安全性。在长安链与隐私计算的融合实践中&#xff0c;开源社区提炼并抽象出多方计算场…

#渗透测试#批量漏洞挖掘#Crocus系统—Download 文件读取

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

LabVIEW用户界面设计原则

在LabVIEW开发中&#xff0c;用户界面&#xff08;UI&#xff09;设计不仅仅是为了美观&#xff0c;它直接关系到用户的操作效率和体验。一个直观、简洁、易于使用的界面能够大大提升软件的可用性&#xff0c;尤其是在复杂的实验或工业应用中。设计良好的UI能够减少操作错误&am…

MySQL8.0 innodb Cluster 高可用集群部署(MySQL、MySQL Shell、MySQL Router安装)

简介 MySQL InnoDB集群&#xff08;Cluster&#xff09;提供了一个集成的&#xff0c;本地的&#xff0c;HA解决方案。Mysq Innodb Cluster是利用组复制的 pxos 协议&#xff0c;保障数据一致性&#xff0c;组复制支持单主模式和多主模式。 InnoDB Cluster组件&#xff1a; …

Effective Objective-C 2.0 读书笔记——内存管理(上)

Effective Objective-C 2.0 读书笔记——内存管理&#xff08;上&#xff09; 文章目录 Effective Objective-C 2.0 读书笔记——内存管理&#xff08;上&#xff09;引用计数属性存取方法中的内存管理autorelease保留环 ARCARC必须遵循的方法命名原则ARC 的自动优化&#xff1…

软件测试覆盖率详解

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、覆盖率概念 覆盖率是用来度量测试完整性的一个手段&#xff0c;是测试技术有效性的一个度量。分为&#xff1a;白盒覆盖、灰盒覆盖和黑盒覆盖&#xff1b;测…

控制玉米株高基因 PHR1 的基因克隆

https://zwxb.chinacrops.org/CN/10.3724/SP.J.1006.2024.33011

windows10本地的JMeter+Influxdb+Grafana压测性能测试,【亲测,避坑】

一、环境&#xff0c;以下软件需要解压、安装到电脑上。 windows10 apache-jmeter-5.6.3 jdk-17.0.13 influxdb2-2.7.11 grafana-enterprise-11.5.1二、配置Influxdb&#xff0c;安装完默认连接http://localhost:8086/。打开连接&#xff0c;配置如下。 开启Influxdb&#xf…

如何在 Java 后端接口中提取请求头中的 Cookie 和 Token

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务) &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1;个人微信&a…

【Python网络爬虫】爬取网站图片实战

【Python网络爬虫】爬取网站图片实战 Scrapying Images on Website in Action By Jackson@ML *声明:本文简要介绍如何利用Python爬取网站数据图片,仅供学习交流。如涉及敏感图片或者违禁事项,请注意规避;笔者不承担相关责任。 1. 创建Python项目 1) 获取和安装最新版…

SAP ABAP VA05增强

SE18 输入增强的BADI名称:BADI_SDOC_WRAPPER 进入后,点击Interface。 进入后,点击显示对象清单。 双击增强类,下面有之前做好的增强类,没有的可以自己创建一个。 IF_BADI_SDOC_WRAPPER~ADAPT_RESULT_COMP 代码 METHOD if_badi_sdoc_wrapper~adapt_result_comp."…

八大排序——简单选择排序

目录 1.1基本操作&#xff1a; 1.2动态图&#xff1a; 1.3代码&#xff1a; 代码解释 1. main 方法 2. selectSort 方法 示例运行过程 初始数组 每轮排序后的数组 最终排序结果 代码总结 1.1基本操作&#xff1a; 选择排序&#xff08;select sorting&#xff09;也…

【清晰教程】本地部署DeepSeek-r1模型

【清晰教程】通过Docker为本地DeepSeek-r1部署WebUI界面-CSDN博客 目录 Ollama 安装Ollama DeepSeek-r1模型 安装DeepSeek-r1模型 Ollama Ollama 是一个开源工具&#xff0c;专注于简化大型语言模型&#xff08;LLMs&#xff09;的本地部署和管理。它允许用户在本地计算机…

【matlab优化算法-17期】基于DBO算法的微电网多目标优化调度

基于蜣螂DBO算法的微电网多目标优化调度 一、前言 微电网作为智能电网的重要组成部分&#xff0c;其优化调度对于降低能耗、减少环境污染具有重要意义。本文介绍了一个基于Dung Beetle Optimizer&#xff08;DBO&#xff09;算法的微电网多目标优化调度项目&#xff0c;旨在通…

如何使用qt开发一个xml发票浏览器,实现按发票样式显示

使用Qt开发一个按发票样式显示的XML发票浏览器&#xff0c;如下图所示样式&#xff1a; 一、需求&#xff1a; 1、按税务发票样式显示。 2、拖入即可显示。 3、正确解析xml文件。 二、实现 可以按照以下步骤进行&#xff1a; 1. 创建Qt项目 打开Qt Creator&#xff0c;创…

解析 JavaScript 面试题:`index | 0` 确保数组索引为整数

文章目录 一、JavaScript 中的数字类型二、按位或运算符 | 的作用&#xff08;一&#xff09;对于整数&#xff08;二&#xff09;对于小数&#xff08;三&#xff09;对于非数字值 三、用于数组索引的意义 在 JavaScript 面试中&#xff0c;常常会涉及到一些看似简单却蕴含着深…