一、枚举类型——常量特定方法

news2024/11/20 20:38:33

Java 的枚举机制可以通过为每个枚举实例编写不同的方法,来赋予它们不同的行为。要实现这一点,你可以在枚举类型中定义一个或多个抽象方法,然后为每个枚举实例编写不同的实现,例如:

ConstantSpecificMethod.java

import java.text.DateFormat;
import java.util.Date;

public enum ConstantSpecificMethod {
    DATE_TIME {
        @Override
        String getInfo() {
            return DateFormat.getDateInstance().format(new Date());
        }
    },
    CLASSPATH {
        @Override
        String getInfo() {
            return System.getenv("CLASSPATH");
        }
    },
    JAVA_HOME {
        @Override
        String getInfo() {
            return System.getenv("JAVA_HOME");
        }
    },
    VERSION {
        @Override
        String getInfo() {
            return System.getProperty("java.version");
        }
    };

    abstract String getInfo();

    public static void main(String[] args) {
        for (ConstantSpecificMethod csm : values()) {
            System.out.println(csm.getInfo());
        }
    }
}

运行结果如下:
在这里插入图片描述

注意:如果 CLASSPATH 和 JAVA_HOME 打印为 null,检查系统环境变量是否已设置(如果已设置但打印还是为 null ,可以尝试重启电脑,我遇到的情况就是重启生效)

你可以通过关联的枚举实例来查找和调用方法,这通常叫作表驱动模式(注意,和前面的命令模式很相似)。

在面向对象编程中,不同的行为和不同的类相关联,通过常量特定方法,枚举类型的 各种实例可以拥有各自的行为,这表明每个实例都是不同的类型。在上面的例子中,每个枚举实例都被视同于“基类" ConstantSpecificMethod 的实例,但调用 getlnfo() 方法时的行为是多态的。

然而,这两者的相似性也只能到此为止,你无法将 enum 实例等同于类类型:

NotClasses.java

enum LikeClasses {
    WINKEN {
        @Override
        void behavior() {
            System.out.println("Behavior1");
        }
    },
    BLINKEN {
        @Override
        void behavior() {
            System.out.println("Behavior2");
        }
    },
    NOD {
        @Override
        void behavior() {
            System.out.println("Behavior3");
        }
    };

    abstract void behavior();
}

public class NotClasses {
    // void f1(LikeClasses.WINKEN instance) {} // 不行
}

javac、javap

在这里插入图片描述

在 f1() 方法中,编译器不允许将枚举实例作为类类型来使用,只要设想一下编译器是如何生成代码的,这一点就说得通了,每个枚举元素都是 LikeClasses 的一个 static final 的实例。

同样,由于它们是静态的,内部枚举中的枚举实例表现得并不像普通的内部类,你无法从外部类访何非静态域或方法 。

再来看一个洗车的例子,每个用户都拿到了一个洗车选项的菜单,每个选项都代表不同的操作,每个选项都可以分配一个常量特定方法,然后用一个 EnumSet 来持有用户的选择。

CarWash.java

import java.util.EnumSet;

public class CarWash {
    public enum Cycle {
        UNDERBODY {
            @Override
            void action() {
                System.out.println("Spraying the underbody");
            }
        },
        WHEELWASH {
            @Override
            void action() {
                System.out.println("Washing the wheels");
            }
        },
        PREWASH {
            @Override
            void action() {
                System.out.println("Loosening the dirt");
            }
        },
        BASIC {
            @Override
            void action() {
                System.out.println("The basic wash");
            }
        },
        HOTWAX {
            @Override
            void action() {
                System.out.println("Applying hot wax");
            }
        },
        RINSE {
            @Override
            void action() {
                System.out.println("Rinsing");
            }
        },
        BLOWDRY {
            @Override
            void action() {
                System.out.println("Blowing dry");
            }
        };

        abstract void action();
    }

    EnumSet<Cycle> cycles = EnumSet.of(Cycle.BASIC, Cycle.RINSE);

    public void add(Cycle cycle) {
        cycles.add(cycle);
    }

    public void washCar() {
        for (Cycle c : cycles) {
            c.action();
        }
    }

    @Override
    public String toString() {
        return cycles.toString();
    }

    public static void main(String[] args) {
        CarWash wash = new CarWash();
        System.out.println(wash);
        wash.washCar();
        // Order of addition is unimportant:
        wash.add(Cycle.BLOWDRY);
        wash.add(Cycle.BLOWDRY); // Duplicates ignored
        wash.add(Cycle.RINSE);
        wash.add(Cycle.HOTWAX);
        System.out.println(wash);
        wash.washCar();
    }
}

运行结果如下:
在这里插入图片描述

定义一个常量特定方法的语法和定义匿名内部类差不多,但是要更简洁一些。

这个例子还展示了 EnumSet 的更多特点,它是一种 Set,所以每个可选洗车项目都只能持有一个选项,用相同的参数对 add() 方法的重复调用会被忽略(这很好理解,因为打开开关一次和多次是一样的) 。另外,添加枚举实例的顺序并不重要——输出顺序由枚举声明的顺序决定。

重写常量特定方法,而不是实现一个抽象方法,这是可能的吗?是的,如以下示例所示:

OverrideConstantSpecific.java

public enum OverrideConstantSpecific {
    NUT, BOLT,
    WASHER {
        @Override
        void f() {
            System.out.println("Overridden method");
        }
    };

    void f() {
        System.out.println("default behavior");
    }

    public static void main(String[] args) {
        for (OverrideConstantSpecific ocs : values()) {
            System.out.print(ocs + ": ");
            ocs.f();
        }
    }
}

运行结果如下:
在这里插入图片描述

虽然枚举确实阻止了某些类型的代码,但是通常来说,可以把它们当作类来实验。

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

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

相关文章

使用 TensorFlow.js 将机器学习引入您的 Web 应用程序

如何使用 TensorFlow.js 在您的 Web 应用程序中实施机器学习 原文作者: Abhay Singh Rathore 机器学习 (ML) 不再是一个崇高、遥不可及的概念。借助 TensorFlow.js 等库&#xff0c;开发人员现在可以将 ML 整合到他们的 Web 应用程序中。例如&#xff0c;您可以创建一个系统&am…

革新智造业丨云和恩墨数据智能产品 zAIoT 将工控设备KPI分析性能提升百倍

点击关注 随着智能制造业的迅猛发展&#xff0c;工控设备在生产过程中起到至关重要的作用。为了确保生产效率和产品质量的提高&#xff0c;企业需要对工控设备进行全面的分析和评估。 工控设备KPI是指在生产线/车间设备的运行和维护过程中&#xff0c;需要监控的关键指标参数&a…

Vue----Vue的模板语法

【原文链接】Vue----Vue的模板语法 Vue 模板语法的描述 Vue使用一种基于HTML的模板语法&#xff0c;使我们能够声明式地将其组件实例的数据绑定到呈现的DOM上&#xff0c;所有的Vue模板都是语法层面合法的HTML&#xff0c;可以被符合规范的浏览器和HTML解析器解析 文本插值 …

Java性能权威指南-总结16

Java性能权威指南-总结16 线程与同步的性能线程池与ThreadPoolExecutor设置最大线程数设置最小线程数 线程与同步的性能 能够轻松编写多线程程序也是Java的一个标志性特征。Java性能方面的吸引力显而易见&#xff1a;如果有两个CPU可用&#xff0c;那么一个应用能够完成的工作…

计算机网络笔记(更新中)

本文是个人笔记&#xff0c;都是概念&#xff0c;没基础不建议看。 绪论 计算机网络的定义 最简单的定义&#xff1a;计算机网络是一些互相连接的、自治的计算机的集合因特网&#xff08;Internet&#xff09;是“网络的网络” 计算机网络的组成&#xff08;物理组成&#x…

STM32单片机(七)ADC模拟数字转换器----第一节:ADC模数转换器

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

autoDL上A100运行wiki出错:NVIDIA A100-PCIE-40GB(最后安装好torch+dgl了);学校服务器加2.X版本pytorch

1、A100运行wiki出错&#xff1a;NVIDIA A100-PCIE-40GB with CUDA capability sm_80 is not compatible with the current PyTorch installation. The current PyTorch install supports CUDA capabilities sm_37 sm_50 sm_60 sm_70. If you want to use the NVIDIA A100-PCIE…

CTFshow-pwn入门-pwn26-pwn28

什么是ASLR 大多数的攻击都基于这样一个前提&#xff0c;即攻击者知道程序的内存布局&#xff0c;需要提前知道shellcode或者其他一些数据的位置。因此&#xff0c;引入内存布局的随机化能够有效增加漏洞利用的难度&#xff0c;其中一种技术就是ASLR&#xff08;Address Space…

Qt颜色、文件、字体对话框

项目目录 界面 一、颜色对话框 QColor color QColorDialog::getColor(QColor(255,0,0));qDebug()<<"r"<<color.red()<<" g "<<color.green()<<" b "<<color.blue(); 二、文件对话框 //文件对话框QString…

《网络安全0-100》-网络攻击方式

网络攻击方式 DoS DDoS攻击 DoS攻击和DDoS攻击都是网络攻击的一种&#xff0c;它们的区别如下&#xff1a; DoS攻击(Denial of Service&#xff0c;拒绝服务攻击)&#xff1a;指攻击者通过向目标计算机或网络发送大量的合法请求&#xff0c;占用其网络资源和带宽&#xff0c;…

Java API

目录 1.JSON 2.多线程 3.网络编程 1.JSON &#xff08;1&#xff09;定义&#xff1a; 1.轻量级的文本数据交换格式 2.具有自我描述性【看到某个JSON数据就能知道它的特点】 3.比XML传输速度快【跨平台】 (2)语法规则&#xff1a; 1.语法&#xff1a; 2.构成要素&#xff…

Cortext-M3系列:M3内核概述(1)

引言&#xff1a; 本系列博客记录的是博主以前学习单片机时期的一些关于MCU内核方面的知识点和笔记&#xff0c;分享给一起学习的小伙伴&#xff0c;也作为复习用处。文中出现的Cortex-M3、CM3、M3均指的是ARM公司的产品Cortex-M3&#xff0c;后面不再赘述。本系列的博客仅仅只…

基于Java共享客栈管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

Go语言包设计指南

1. Go包的认知 1.1 Go包是基本功能单元 我们知道Go包是Go编程语言中的一个重要概念&#xff0c;它是一组相关的Go源代码文件。并且&#xff0c;在Go中&#xff0c;每个Go源文件都必须属于一个包。 Go包是一个逻辑上独立的单元&#xff0c;是Go的基本功能单元&#xff0c;用来做…

Redis安装说明(heima)

Redis安装说明&#xff08;heima&#xff09; 笔者的redis(Linux版)的下载链接地址&#xff1a;https://download.csdn.net/download/weixin_46411355/87926624 笔者的redis图形化桌面客户端&#xff0c;下载链接地址为&#xff1a;https://download.csdn.net/download/weixin…

Python单元测试框架之pytest -- 断言

对于测试来讲&#xff0c;不管是功能测试&#xff0c;自动化测试&#xff0c;还是单元测试。一般都会预设一个正确的预期结果&#xff0c;而在测试执行的过程中会得到一个实际的结果。测试的成功与否就是拿实际的结果与预期的结果进行比较。这个比的过程实际就是断言&#xff0…

PHP实战开发24-一定要知道PHP中反射的强大应用

文章目录 一、前言1.1 关于反射1.2 PHP中的反射 二、反射的应用2.1 自动注入2.2 动态调用方法2.3 注解解析 总结 一、前言 本文已收录于PHP全栈系列专栏&#xff1a;PHP快速入门与实战 1.1 关于反射 反射是一种编程语言的特性&#xff0c;它允许程序在运行时获取和操作对象的…

kotlin从入门到精通之内置类型

基本类型 声明变量 val&#xff08;value的简写&#xff09;用来声明一个不可变的变量&#xff0c;这种变量在初始赋值之后就再也不能重新赋值&#xff0c;对应Java中的final变量。 var&#xff08;variable的简写&#xff09;用来声明一个可变的变量&#xff0c;这种变量在初始…

CUDA线程的线程层次结构,以及单个线程threadIdx如何使用stride来进行跳步操作,同时对多个数据进行计算

线程层次的概念&#xff1a; 简单说&#xff0c;就是一个grid有多个block,一个block有多个thread. grid有多大&#xff0c;用gridDim表示它有多少个block&#xff0c;具体分为gridDim.x, gridDim.y&#xff0c;gridDim.z。 block有多大&#xff0c;用blockDim表示它有多少个t…

SpringBoot项目结合@Slf4j将日志记录到磁盘和数据库

文章目录 1、背景介绍2、存本地2.1、配置文件2.2、使用 3、存数据库3.1、配置文件改造3.2、过滤器编写3.3、表准备3.4、添加依赖3.5、测试 4、优化4.1、日志定期删除4.2、分库处理4.3、环境 5、总结 1、背景介绍 现在我一个SpringBoot项目想记录日志&#xff0c;大概可以分为下…