跳到主要内容

第19章-枚举

思考:如果我们有一个运动的类,里面有一个季节属性,其他方法,比如跑步方法,会根据季节穿不同的衣服。这个季节属性的类型如何设计?像下面的代码使用整型、字符串类型,可以吗?有什么问题?

//季节,1:春季、2:夏季、3:秋季、4:冬季
private Integer season;
//季节,可以是春季、夏季、秋季、冬季
private String season;

存在的问题

  1. 不能在编译期限定季节的值,如Integer的值设置为5,String类型设置为“无聊季”
  2. 在使用时,做不到一看属性,就知道输入什么值是代表什么意义,如Integer类型的season赋值2时,并一能一眼就知道2是代表夏季
  3. 在使用后,如果业务变化,显示的内容变化无法扩展,如String类型的”春季“改为”春天“

概述

  • 枚举,是将可选的值,一个一个列出来,并在使用时进行限定
  • 枚举最终存储的值是整数,分别是0、1、2、...
  • 继承于java.lang.Enum类
  • 解决上述属性使用过程中,需要限定某些值的业务诉求

定义枚举

  • 使用关键字enum进行定义

  • 命名规范

    • 枚举名,使用大驼峰
    • 枚举值,使用全大写,多个单词间使用_连接
  • 定义方式

    • 方式1,简单方式;使用季节实例

      package com.bjpowernode.demo;

      /**
      * 季节枚举
      */
      public enum Season {
      //分别代表整型0,1,2,3
      SPRING,SUMMER,AUTUMN,WINTER
      }
    • 方式2,带参数的枚举

      package com.bjpowernode.demo;

      /**
      * 季节枚举,带参数的枚举
      */
      public enum Season {
      //分别代表整型0,1,2,3
      SPRING("春季",1),SUMMER("夏季",3),AUTUMN("秋季",5),WINTER("冬季",7);

      //属性
      private String seasonName;
      private Integer seasonIndex;

      //构造
      Season(String seasonName,Integer seasonIndex) {
      this.seasonName = seasonName;
      this.seasonIndex = seasonIndex;
      }

      public String getSeasonName() {
      return seasonName;
      }

      public Integer getSeasonIndex() {
      return seasonIndex;
      }
      }

使用枚举

  • 枚举定义好后,就可以应用在其他相关业务代码中

  • 枚举也是引用数据类型,作为成员变量时,默认值为null

  • 枚举值,可以通过”枚举名.枚举值“方式访问

  • 使用方式

    • 方式1,使用枚举

      package com.bjpowernode.demo;

      /**
      * 枚举实例,遍历枚举
      */
      public class EnumDemo {
      public static void main(String[] args) {
      //使用枚举,简单方式
      Season season = Season.WINTER;
      //枚举常用输出
      System.out.println(season); //枚举名称
      System.out.println(season.ordinal()); //枚举值
      //带参数的枚举属性
      System.out.println(season.getSeasonName()); //参数1
      System.out.println(season.getSeasonIndex()); //参数2
      }
      }
    • 方式2,直接应用到业务中;运动类中使用枚举

      package com.bjpowernode.demo;

      /**
      * 运动类
      */
      public class Sport {
      //季节,数据类型是枚举,则表示只能使用Season定义的值
      private Season season;

      public Season getSeason() {
      return season;
      }

      public void setSeason(Season season) {
      this.season = season;
      }

      public static void main(String[] args) {
      //创建对象
      Sport sport = new Sport();
      //设置属性值
      sport.setSeason(Season.WINTER);

      //输出枚举
      System.out.println(sport.getSeason());
      //输出枚举值,序数
      System.out.println(sport.getSeason().ordinal());
      //带参数的枚举属性
      System.out.println(sport.getSeason().getSeasonName()); //参数1
      System.out.println(sport.getSeason().getSeasonIndex()); //参数2
      }
      }

【练习】

  1. 练习应用实例内容,完成代码编写

常用方法

  • ordinal,获取枚举值,从0开始,分别为0、1、2、...

  • values,获取枚举的所有值

  • valueOf,从字符串中获取枚举,如果字符串名称不在定义的范围内,将会抛出异常java.lang.IllegalArgumentException

  • 方法实例

    • 方法实例1,常用方法

      package com.bjpowernode.demo;

      /**
      * 枚举实例
      */
      public class EnumDemo {
      public static void main(String[] args) {
      //遍历枚举
      for (Season season : Season.values()) {
      System.out.println(season);
      System.out.println(season.ordinal());
      }
      //从字符串获取枚举,如果名称不存在,会抛出异常,尝试SPRING2
      Season season = Season.valueOf("SPRING");
      System.out.println(season);
      }
      }

【练习】

  1. 练习应用实例内容,完成代码编写

实战和作业

  1. 重构程序,重构"第11章-多态"的people项目,引入信仰枚举,要求如下
    1. 定义信仰枚举,包含无、基督教、伊斯兰教、佛教等枚举值
    2. 给父类People,添加信仰属性,使用信仰枚举
    3. 给每个各个国家的人对象设置信仰,并在speakHi中添加信仰介绍
  2. 【扩展】重构程序,重构"第11章-多态"的实战与作业中的第2题计算工资题,引入员工职级枚举,要求如下
    1. 定义员工职级枚举,包含员工、组长、经理、总监、CEO等枚举值
    2. 重构管理者加500元工资的逻辑,修改成根据员工职级设置津贴,组长、经理、总监、CEO的津贴分别为200、400、600、1000元
    3. 重构财务人员发放工资逻辑,在工资信息中,显示员工职级