JavaSE——面向对象高级三(3/5)-枚举(认识枚举、拓展:抽象枚举、用枚举实现单例模式、枚举的应用场景)

简介: JavaSE——面向对象高级三(3/5)-枚举(认识枚举、拓展:抽象枚举、用枚举实现单例模式、枚举的应用场景)

枚举的概述

认识枚举

  • 枚举是一种特殊类。

枚举类的格式

修饰符 enum 枚举类名{

       名称1,名称2,...;

       其他成员...

}

public enum A{
    X,Y,Z;
    ...
}

注意

  • 枚举类中的第一行,只能写一些合法的标识符(名称),多个名称用逗号隔开。
  • 这些名称,本质是常量,每个常量都会记住枚举类的一个对象

枚举类的特点

public enum A{
    X,Y,Z;
}

实际上完整代码为:

Complied from "A.java"
public final class A extends java.lang.Enum<A>{
    public static final A X = new A();
    public static final A Y = new A();
    public static final A Z = new A();
}

具有以下特点:

  • 枚举类的第一行只能罗列一些名称,这些名称都是常量,并且每个常量记住的都是枚举类的一个对象
  • 枚举类的构造器都是私有的(写不写都只能是私有的),因此,枚举类对外不能创建对象。
  • 枚举都是最终类,不可以被继承。
  • 枚举类中,从第二行开始,可以定义类的其他各种成员。
  • 编译器为枚举类新增了几个方法,并且枚举类都是继承:java.lang.Enum类的,从enum类也会继承到一些方法。

第一点:枚举类的第一行都是常量,记住的是枚举类的对象


A a = A.Y;

因为枚举类的第一行都是常量,记住的是枚举类的对象,所以我们可以直接用枚举类得到里面的象,例如:枚举类名称.枚举类常量1、枚举类名称.枚举类常量2;A.X、A.Y。

第二点:枚举类的构造器是私有的,不能对外创建对象。

public class Test{
    public static void main(String[] args){
        A a = new A(); //会报错
        //枚举类不能对外创建对象
    }
}

第三点:枚举类提供了一些额外的API

A[] a1 = A.values(); //拿到全部对象
A a2 = A.valueOf("Z"); //拿到其中一个对象
System.out.println(a2.name()); //输出结果为Z对象的name
System.out.println(a2.ordinal()); //索引

都是为枚举类新增的一些API。

拓展:抽象枚举

抽象枚举简单来说,就是枚举类里面定义了抽象方法的枚举类。

抽象枚举在创建自身的对象时,必须要重写方法,所以直接在第一行中进行方法重写:

public enum B{
    X(){
        @Override
        public void go(){
        }
    },Y(){
        @Override
        public void go(){
        }
    };
    
    private String name; //第一行之后就可以正常写变量了
    
    public abstract void go(); //抽象方法
    
    public String getName(){
        return name;
    }
    public String setName(name){
        this.name = name;
    }
}

写构造器时,可以不用写修饰符,默认为private。

public enum B{
    X(){
        @Override
        public void go(){
        }
    },Y(){
        @Override
        public void go(){
        }
    };
    
    /* private */ B(){
    }
    /* private */ B(String name){
        this.name;
    }
 
    private String name; 
    
    public abstract void go(); //抽象方法
    
    public String getName(){
        return name;
    }
    public String setName(name){
        this.name = name;
    }
}

如果把无参构造器去掉,就会报错,因为前面枚举类创建的对象重写方法时要调用到无参构造器。

当然,也可以调用有参构造器

public enum B{
    X(){
        @Override
        public void go(){
        }
    },Y("张三"){
        @Override
        public void go(){
            System.out.println(getName() + "在跑~");
        }
    };
    
    B(){
    }
    B(String name){
        this.name;
    }
 
    private String name; 
    
    public abstract void go(); //抽象方法
    
    public String getName(){
        return name;
    }
    public String setName(name){
        this.name = name;
    }
}
public class Test{
    public static void main(String[] args){
        B y = B.Y;
        y.go();
    }
}

运行结果为:

张三在跑~

这个过程是:Y对象在用B枚举类创建自己这个对象,调用B的有参构造器,传入参数“张三”,存储在name变量中;且因为是抽象枚举,创建Y对象时需要重写其所有抽象方法,重写go方法时取到name变量的值“张三”并输出。

用枚举实现单例模式

使用枚举是可以直接实现单例模式的,


复习一下单例设计模式:

       一个类可以new出很多对象,但对于某个应用场景下,我们希望这个类只能有一个对象这就是单例设计模式所解决的问题。也就是说,单例设计模式是确保一个类只有一个对象,我们学过饿汉式单例和懒汉式单例,前者是先把对象创建好,后者则在使用该设计模式时再进行创建。

       写法:


  • 把类的构造器私有。
  • 定义一个类变量记住类的一个对象。·
  • 定义一个类方法,返回对象。

用枚举类的方式实现单例:

public enum C{
    X; //单例
}

枚举的应用场景

  • 用来表示一组信息,然后作为参数进行传输。

(可以类比C语言的枚举类型变量)

如果选择定义一个一个的常量来表示一组信息,并作为参数传输,那么其参数值不受约束

而选择定义枚举表示一组信息,并作为参数传输,代码可读性好,参数值得到了约束,对使用者更友好

例如:

public class Constant{
    public static final int BOY = 0;
    public static final int GIRL = 1;
}
 
public class Test{
    public static void main(String[] args){
        //check(1);
        //check(21);  //传入参数不受约束
        check(Constant.BOY);
    }
    public static void check(int sex){
        switch(sez){
            case Constant.BOY:
                ...
                break;
            case Constant.GIRL:
                ...
                break;
        }
    }
}

如果用常量做信息标志和分类,就存在传入参数不受约束的问题。

所以就开始用枚举了:

public enum Constant2{
    BOY,GIRL;  //定义枚举类型
}
 
public class Test{
    public static void main(String[] args){
        //check(1);
        //check(21);  //传入参数不受约束
        check(Constant2.BOY);
    }
    public static void check(Constant2 sex){
        switch(sez){
            case BOY: //Constant.BOY前缀可以省略
                ...
                break;
            case GIRL:
                ...
                break;
        }
    }
}

虽然枚举做信息标志和分类比较好,但是在实际中可能会发现还是很多人用常量,主要是因为常量用起来比较简单,其他原因就是常量也有一些优势,比如可以定义不同类型的常量,使用起来比较灵活。

所以两种方式都会使用到,并没有相互淘汰掉谁。


END



目录
相关文章
|
存储 NoSQL Java
Java数据库编程指南:实现高效数据存储与访问
【4月更文挑战第2天】Java开发者必须掌握数据库编程,尤其是JDBC,它是连接数据库的标准接口。使用Spring JDBC或JPA能简化操作。选择合适的JDBC驱动,如MySQL Connector/J,对性能至关重要。最佳实践包括事务管理、防SQL注入、优化索引和数据库设计。NoSQL数据库如MongoDB也日益重要,Java有对应的驱动支持。理解这些概念和技术是构建高效数据库应用的基础。
431 4
Java数据库编程指南:实现高效数据存储与访问
|
JavaScript 搜索推荐 程序员
Vuepress + gitee五分钟免费搭建个人博客(保姆级教程)
前言 作为一个程序员,没有折腾过个人博客是不算完整的。技术文章的输出是我们程序员能力的一种体现,也是一种非常好的个人总结。 市面上有很多搭建个人博客的工具或框架,包括hexo、wordpress等等。不可否认,市面上有些博客系统做得很好,博客主题也很丰富,但是往往存在一个问题:比较重。 作为一个Vue程序员,我就比较推荐使用vuepress搭建个人博客,因为它毕竟是Vue出品的,大家熟知的vue官方就是利用vuepress搭建的。 本篇文章就从零开始教大家搭建一个免费的博客,零基础小白也可以学习哦!
3905 0
Vuepress + gitee五分钟免费搭建个人博客(保姆级教程)
|
4月前
|
人工智能 自然语言处理 Java
从青铜到王者,DeepSeek+Spring AI 搭建 RAG 知识库
本文介绍了基于RAG(检索增强生成)技术构建知识库的原理与实现方法。RAG通过结合检索与生成模型,提升大语言模型在问答任务中的准确性与相关性,有效缓解“幻觉”问题。文章还详细讲解了如何利用DeepSeek与SpringAI搭建高效RAG系统,并提供了完整的Java代码示例,帮助开发者快速实现文档处理、向量存储与智能问答功能。适用于智能客服、内容生成、辅助决策等多个场景。
1287 2
|
6月前
|
存储 安全 Java
2025 年一线互联网大厂最新高质量 Java 面试八股文整理及答案汇总
本文整理了一线互联网大厂最新的高质量Java面试八股文及其答案,涵盖Java基础、集合框架与多线程三大核心模块。内容包括面向对象与面向过程的区别、`equals`与`==`的差异、`final`和`static`的用法、集合类如`ArrayList`与`LinkedList`的对比、`HashMap`的工作原理及其与`Hashtable`的区别,以及多线程中的线程创建方式、生命周期、上下文切换和死锁等知识点。通过系统化的梳理与解析,帮助读者高效备考Java面试,掌握核心技术要点。资源可从文末链接下载。
1353 40
|
Java 关系型数据库 MySQL
如何用java的虚拟线程连接数据库
本文介绍了如何使用Java虚拟线程连接数据库,包括设置JDK版本、创建虚拟线程的方法和使用虚拟线程连接MySQL数据库的示例代码。
299 6
如何用java的虚拟线程连接数据库
|
7月前
|
测试技术 UED
全新开源通义千问Qwen3,它来了!
Qwen3是通义千问系列的最新模型,融合推理与非推理模式,兼具QwQ和Instruct模型能力。提供多种尺寸,包括235B-A22B、30B-A3B及六个Dense模型,大幅提升数学、代码、逻辑推理和对话能力,达到业界领先水平。旗舰模型Qwen3-235B-A22B在多场景测试中表现优异,小型模型如Qwen3-4B性能媲美大模型。用户可在阿里云百炼平台免费体验各100万Token。
7351 4
全新开源通义千问Qwen3,它来了!
|
存储 安全 芯片
内存卡无法格式化怎么办?这5个办法可以帮你
在日常生活中,我们常常使用内存卡来存储照片、视频、文档等重要数据。然而,有时候在尝试格式化内存卡时,我们可能会遇到无法格式化的问题。这种情况令人十分烦恼,因为这不仅影响了内存卡的使用,还可能导致数据丢失。那么,当内存卡无法格式化时,我们应该怎么办呢?本文将为您提供一些实用的解决方案,帮助您解决内存卡无法格式化的问题。
内存卡无法格式化怎么办?这5个办法可以帮你
|
NoSQL Java API
分布式锁的实现原理与应用场景,5 分钟彻底搞懂!
本文详细解析了分布式锁的实现原理与应用场景,包括线程锁、进程锁和分布式锁的区别,以及分布式锁的四种要求和三种实现方式(数据库乐观锁、ZooKeeper、Redis)。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
分布式锁的实现原理与应用场景,5 分钟彻底搞懂!
|
安全 关系型数据库 MySQL
【IIS搭建网站】本地电脑做服务器搭建web站点并公网访问「内网穿透」
【IIS搭建网站】本地电脑做服务器搭建web站点并公网访问「内网穿透」

热门文章

最新文章