在某些情况,一个类的对象是有限而且是固定的,例如季节类,只有春夏秋冬四个对象,这种实例有限且固定的类,成为枚举类

枚举类概念和作用

在JAVA5之前的枚举用法是这样的:

public static final int SEASON_SPRING = 1;
public static final int SEASON_SUMMER = 2;
public static final int SEASON_FALL = 3;
public static final int SEASON_WINTER = 4;
public class Season
{// 把Season类定义成不可变的,将其成员变量也定义成final的private final String name;private final String desc;public static final Season SPRING= new Season("春天", "趁春踏青");public static final Season SUMMER= new Season("夏天", "夏日炎炎");public static final Season FALL= new Season("秋天", "秋高气爽");public static final Season WINTER= new Season("冬天", "围炉赏雪");public static Season getSeason(int seasonNum){switch (seasonNum){case 1 :return SPRING;case 2 :return SUMMER;case 3 :return FALL;case 4 :return WINTER;default :return null;}}// 将构造器定义成private访问权限private Season(String name, String desc){this.name = name;this.desc = desc;}// 只为name和desc提供getter方法public String getName(){return this.name;}public String getDesc(){return this.desc;}
}

在JAVA5之后新增了enum关键字,它与class,interface关键字的地位相同,用于定义枚举类,枚举类一样可以有自己的成员变量、方法,可以实现一个或多个接口,也可以定义自己的构造器
一个Java源文件只能有一个public访问权限的枚举类,并且这个Java源文件的文件名必须与该枚举类的类名相同

枚举类与普通类的不同

  • 枚举类可以实现一个或多个接口,使用enum定义的枚举类默认继承了java.lang.Enum类而不是Object类,枚举类不能显示的继承其父类,java.lang.Enum实现了java.lang.Serializable和java.lang.Comparable接口
  • 使用enum定义的非抽象的枚举类默认会使用final修饰
  • 枚举类的构造器只能使用private访问控制符,如果省略了则系统默认会加上private修饰,因此枚举类不能派生子类
  • 枚举类所有实例必须在枚举类的第一行显示的列出,否则这个枚举类永远不能产生实例,列出这些实例,系统会自动添加public static final修饰,无需显示添加
public enum SeasonEnum
{   // 显示的列出4个枚举类 SPRING, SUMMER, FALL, WINTER;
}

显示的使用枚举类的实例EnumClass.variable,例如SeasonEnum.SPRING

public class EnumTest
{public void judge(SeasonEnum s){// switch语句里的表达式可以是枚举值switch (s){case SPRING:System.out.println("春暖花开,正好踏青");break;case SUMMER:System.out.println("夏日炎炎,适合游泳");break;case FALL:System.out.println("秋高气爽,进补及时");break;case WINTER:System.out.println("冬日雪飘,围炉赏雪");break;}}public static void main(String[] args){// 枚举类默认有一个values方法,返回该枚举类的所有实例for (var s : SeasonEnum.values()){System.out.println(s);}// 使用枚举实例时,可通过EnumClass.variable形式来访问new EnumTest().judge(SeasonEnum.SPRING);}
}

switch表达式使用了SeasonEnum对象作为表达式(JDK1.5增加了枚举后对switch进行了扩展),switch的控制表达式可以是任何枚举类型,并且case表达式中的值直接使用枚举值的名字,无需添加枚举类作为限定

java.lang.Enum类中的几个方法

  • int compareTo(E o):
  • String name():
  • int ordinal():
  • String toString():
  • public static <T extends Enum>T valueOf(ClassenumType, String name):

枚举类的成员变量、方法和构造器

public enum Gender
{MALE, FEMALE;public String name;
}public class GenderTest
{public static void main(String[] args){// 通过Enum的valueOf()方法来获取指定枚举类的枚举值Gender g = Enum.valueOf(Gender.class, "FEMALE");// 直接为枚举值的name实例变量赋值g.name = "女";// 直接访问枚举值的name实例变量System.out.println(g + "代表:" + g.name);}
}

枚举类用起来根普通类区别不大,只是创建对象的方式不同,枚举类实例只能是枚举值而不是通过new来创建枚举类对象
然而为了更好的封装性,不应该允许直接访问到类的成员变量,而是用方法来控制,枚举类也不例外

public enum Gender
{MALE, FEMALE;private String name;public void setName(String name){switch (this){case MALE:if (name.equals("男")){this.name = name;}else{System.out.println("参数错误");return;}break;case FEMALE:if (name.equals("女")){this.name = name;}else{System.out.println("参数错误");return;}break;}}public String getName(){return this.name;}
}
public class GenderTest
{public static void main(String[] args){Gender g = Gender.valueOf("FEMALE");g.setName("女");System.out.println(g + "代表:" + g.getName());// 此时设置name值时将会提示参数错误。g.setName("男");System.out.println(g + "代表:" + g.getName());}
}

枚举类通常设计成不可变类,他的成员变量值不应该允许改变,因此建议使用private final修饰,同时如果所有的成员变量都使用了private final修饰,则必须在构造器为这些成员变量指定初始值(或者在定义成员变量时指定默认值,或者在初始化块中指定初始值)

public enum Gender
{// 此处的枚举值必须调用对应构造器来创建MALE("男"), FEMALE("女");private final String name;// 枚举类的构造器只能使用private修饰private Gender(String name){this.name = name;}public String getName(){return this.name;}
}

当为枚举类创建了一个Gender(String name)构造器后,列出的枚举值就应该如代码所示来完成,实际上枚举类中列出枚举值时,就是调用构造器创建枚举对象,只是不需要new,不需要显示调用构造器

实现接口的枚举类

枚举类可以实现一个或者多个接口,与普通类实现一个或多个接口一样,枚举类实现接口时,也需要实现该接口所包含的方法

public interface GenderDesc
{void info();
}
public enum Gender implements GenderDesc
{// 此处的枚举值必须调用对应构造器来创建MALE("男"), FEMALE("女");// 此处的枚举值必须调用对应构造器来创建private final String name;// 枚举类的构造器只能使用private修饰private Gender(String name){this.name = name;}public String getName(){return this.name;}// 增加下面的info()方法,实现GenderDesc接口必须实现的方法public void info(){System.out.println("这是一个用于用于定义性别的枚举类");}
}

如果要每个枚举值在调用该方法时呈现出不同的行为则需要让每个枚举值分别来实现该方法

    MALE("男")// 花括号部分实际上是一个类体部分// 枚举类的匿名内部子类{public void info(){System.out.println("这个枚举值代表男性");}},FEMALE("女"){public void info(){System.out.println("这个枚举值代表女性");}};

编译时会生成三个文件Gender.class/Gender$1.class/Gender$2.class

包含抽象方法的枚举类

并不是所有的枚举类都使用final修饰,非抽象的枚举类才默认使用final修饰,对于一个抽象枚举类来说,只要它包含了抽象抽象方法,它就是个抽象枚举类,系统默认使用abstract修饰

public enum Operation
{// 定义枚举值时为抽象方法提供实现,否则报错// 枚举类里定义抽象方法,不需要把枚举类也用abstract修饰,系统会自动加上PLUS{public double eval(double x, double y){return x + y;}},MINUS{public double eval(double x, double y){return x - y;}},TIMES{public double eval(double x, double y){return x * y;}},DIVIDE{public double eval(double x, double y){return x / y;}};// 为枚举类定义一个抽象方法// 这个抽象方法由不同的枚举值提供不同的实现public abstract double eval(double x, double y);public static void main(String[] args){System.out.println(Operation.PLUS.eval(3, 4));System.out.println(Operation.MINUS.eval(5, 4));System.out.println(Operation.TIMES.eval(5, 4));System.out.println(Operation.DIVIDE.eval(5, 4));}
}

Java面向对象系列[v1.0.0][枚举类]相关推荐

  1. Java面向对象系列[v1.0.0][类加载器]

    类加载器负责将.class文件加载到内存中,并为它生成对应的java.lang.Class对象 类加载机制 类加载器负责加载所有的类,并未所有被载入内存中的类生成一个java.lang.Class实例 ...

  2. Java面向对象系列[v1.0.0][SQL语法之DDL]

    SQL语法基础 SQL全称是Structured Query Language也就是结构化查询语言,它是操作和检索关系数据库的标准语言,标准的SQL语句可以用于操作任何关系数据库,标准的SQL语句通常 ...

  3. Java面向对象系列[v1.0.0][泛型基础]

    Java5增加泛型支持,很大程度上是为了让集合记住其元素的数据类型,在此之前不用泛型的话,一旦把一个对象放进Java集合中,集合就会忘记对象的类型,把所有的对象当成Object类型处理,从集合里取出对 ...

  4. Java面向对象系列[v1.0.0][泛型进阶]

    所谓泛型,就是允许在定义类.接口.方法时使用类型形参,这个类型形参(或者叫泛型)将在声明变量.创建对象.调用方法时动态地指定(即传入实际的类型参数也可称为类型实参) Java5改写了集合框架中的全部接 ...

  5. Java面向对象系列[v1.0.0][SQL语法之数据库约束]

    数据库约束 所有关系型数据库都支持对数据表使用约束,在表面上是强制执行的数据校验规则,通过约束可以更好的的保证数据表里数据的完整性 大部分数据库支持5中完整性约束 NOT NULL:非空约束,指定某列 ...

  6. Java自动化测试系列[v1.0.0][TestNG测试开发环境配置]

    基于之前写的一篇文章Java自动化测试系列[v1.0.0][Maven开发环境]的基础上,阐述如何配置单元测试框架TestNG的测试开发环境 创建Maven项目 启动IDEA,点击Create New ...

  7. Java基础之面向对象的概念 继承---组合----枚举类

    Java基础之面向对象的概念 继承---组合----枚举类 本章作为面向对象概念的最后一篇,但是作为一名java程序员在面向对象的这条路上还很长. 一.继承与组合简介 继承是实现类重用的重要手段,但是 ...

  8. Java面向对象编程入门练习:Manager类继承Employee类并实现求得员工平均业绩

    Java面向对象编程入门练习:Manager类继承Employee类并实现求得员工平均业绩 请定义一个Manager类,该类继承Employee类,并定义两个变量及一个构造方法,两个变量:depart ...

  9. 阿里巴巴Java开发手册v1.2.0版

    最近在忙毕设,读了阿里java开发手册后,发现可以更好的读懂别人的代码了,一些文件之间的关系通过命名就能看出了.对自己养成良好的编码风格也有极大的帮助. 本手册仅供大家交流.学习及研究使用,禁止用于商 ...

  10. 阿里巴巴Java开发手册v1.2.0网页版

    前言 一 .编程规约 ( 一 ) 命名风格 ( 二 ) 常量定义 ( 三 ) 代码格式 ( 四 ) OOP规约 ( 五 ) 集合处理 ( 六 ) 并发处理 ( 七 ) 控制语句 ( 八 ) 注释规约 ...

最新文章

  1. mongodb query
  2. 【Spring框架家族】SpringBoot基本介绍
  3. 攻防世界dice_game(pwn)
  4. Python PyPI中国镜像
  5. html如何调整打印区域,怎么调整excel打印区域_教你调整excel打印区域的方法-系统城...
  6. java json 转map_JAVA | 基于Fastjson的JSON串序列化和反序列化模板总结
  7. Java和C++的对照
  8. android 8.0图标适配
  9. 中国银联在线支付接口开发——前台支付
  10. python 字符串转ASCII码
  11. 进来看新手该怎么选择自己的第一个平台——shopee、lazada、速卖通版
  12. Linux环境下安装Redis(保姆级教程)
  13. 利用WebBrowser彻底解决Web打印问题
  14. word 以嵌入式插入图片显示不全,被文字掩盖在下方
  15. layer遮罩层 简单的遮罩层
  16. mac 远程桌面连接工具 Microsoft Remote Desktop for Mac 的安装与使用
  17. python入门笔记之初步了解代码
  18. 简单的Windows游戏-第1部分:游戏框架
  19. 评价分布式系统的常用指标
  20. 计算机网络【java面试题】

热门文章

  1. 安卓Native Memory Leak(本地服务内存泄露)分析
  2. 取消wps右键菜单_如何给你的WPS去广告!
  3. 国产DeFi,困在币价里
  4. 冰刃(IceSword)的使用方法(高级篇)
  5. 【华为MateBook13】更换1TB固态硬盘SSD+重装win10系统+安装NVIDIA显卡驱动+电脑管家+指纹驱动+蓝牙驱动+Office激活
  6. 金蝶软件界面文字全部变为乱码解决办法
  7. free源码分析---1
  8. linux 分区 intel raid,linux on intel sata raid
  9. jcp jsr_Oracle提交了第三次JCP改革JSR,以提高透明度
  10. c#加粗代码_C# 字体加粗按钮