枚举

枚举是一个被命名的整型常数的集合,用于声明一组带标识符的常数。

在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。

现实生活种的枚举:一个星期只有7天,一年四季只有春夏秋冬,人类的性别只有男女。
通俗点说:枚举就是固定数的集合。

  1. 枚举(enumeration,简写enum)
  2. 枚举是一组常量的集合
  3. 枚举可以理解成一种特殊的类,里面只包含一组有限的特定的对象

在java中有两种方式可以实现枚举。自定义枚举和使用enum关键字实现枚举

自定义实现枚举

自定义实现枚举需要满足几个条件:

  1. 将构造器私有化,防止别人再创建对象
  2. 不提供set方法,防止别人修改
  3. 一般枚举类的对象或属性会使用static+final修饰,实现底层优化
  4. 定义枚举类时就要创建好固定的对象且通过static对外暴露

案例演示:
一年四季。(一年只有四个季节,不可能少或者多)

public class enum11 {
    public static void main(String[] args) {
        System.out.println(Season.SPRING);//自动使用toString
        System.out.println(Season.SUMMER);
        System.out.println(Season.WINTER);
        System.out.println(Season.AUTUMN);
    }
}
class Season{//自定义枚举类
    private String name;
    private String climate;
    private Season(String name, String climate) {//构造器私有化
        this.name = name;
        this.climate = climate;
    }
    public static final Season SPRING = new Season("春天","温暖");//内部直接创建对象且static final修饰
    public static final Season SUMMER = new Season("夏天","炎热");
    public static final Season AUTUMN = new Season("秋天","凉爽");
    public static final Season WINTER = new Season("冬天","寒冷");
    public String getName() {
        return name;
    }
    public String getClimate() {
        return climate;
    }
    @Override
    public String toString() {
        return "Season{" +
                "name='" + name + '\'' +
                ", climate='" + climate + '\'' +
                '}';
    }
}

enum关键字实现枚举

在java中可以直接使用enum关键字来快速定义一个枚举,但是有一定的语法要求。

  1. 使用enum关键字替代class,表明这是一个枚举
  2. 内部定义对象时直接使用 --常量对象名(参数列表);来创建对象
  3. 如果有多个常量对象,使用逗号,分隔即可
  4. 如果使用enum关键字定义枚举,必须将定义常量对象写在前面。

enum定义枚举演示

public class enum11 {
   public static void main(String[] args) {
       System.out.println(Season.SPRING);//自动使用toString
       System.out.println(Season.SUMMER);
       System.out.println(Season.WINTER);
       System.out.println(Season.AUTUMN);
   }
}
enum Season{//自定义枚举类
   //内部直接创建对象且static final修饰
   SPRING("春天","温暖"),SUMMER("夏天","炎热"),WINTER("秋天","凉爽"),AUTUMN("冬天","寒冷");
   private String name;
   private String climate;
   private Season(String name, String climate) {//构造器私有化
       this.name = name;
       this.climate = climate;
   }
   public String getName() {
       return name;
   }
   public String getClimate() {
       return climate;
   }
   @Override
   public String toString() {
       return "Season{" +
               "name='" + name + '\'' +
               ", climate='" + climate + '\'' +
               '}';
   }
}

使用enum关键字定义枚举注意事项

  1. 使用enum关键字定义枚举时会默认继承enum类
  2. 自定义枚举对象时public static final SPRING = new Season(“春天”,“温暖”),在使用enum关键字时可以简化成SPRING (“春天”,“温暖”)。且当有多个对象实参不一样时,会自动找到对应的构造器。
  3. 使用enum关键字定义枚举时,当定义对象要使用默认无参构造器时,实参列表和括号可以省略
  4. 如果要定义多个枚举对象,使用,号间隔,最后一个有分号结尾;
  5. 枚举对象必须放在枚举类的首行

enum关键字定义枚举练习
1.下列语法是否正确,为什么

enum Gender{
 BOY,GIRL;
 }

正确,BOY和GIRL自动调用无参构造器,没有实参可以把括号省略

2.下面代码会输出什么

enum Gender2{
 BOY,GIRL;
 }
 另一个类的main方法中
 Gender2 boy = Gender2.BOY;
 Gender2 boy2 = Gender2.BOY;
 System.out.println(boy);
 System.out.println(boy2 == boy);

它把BOY的地址给了另外两个引用,然后输出boy,会自动中调toString方法,由于Gender2没有重写,所以会找Gender2的父类enum类的toString。输出BOY,然后两个引用都是指向同一个地址,输出true

enum类常用方法

因为每个用enum关键字修饰的枚举都会默认继承enum,所以enum的方法,子类枚举也可以用

  1. toString();
  2. name();返回当前对象名(常量对象名),子类不能重写
  3. ordinal();返回当前对象位置号,对象的编号。从0开始
  4. values();将当前枚举类中的所有常量对象,汇合在一个数组,且返回这个数组
  5. valuesOf();用实参传入的字符串,到枚举类中查找有没有叫这个名字的对象,如果有就返回这个对象,没有就报错
  6. compareTo();将两个枚举常量对象的编号相减

各方法演示:

public class enum11 {
    public static void main(String[] args) {

//    2. name();返回当前对象名(常量对象名),子类不能重写
        System.out.println(Season.SUMMER.name());
//    3. ordinal();返回当前对象位置号,对象的编号。从0开始
        System.out.println(Season.SUMMER.ordinal());
//    4. values();将当前枚举类中的所有常量对象,汇合在一个数组,且返回这个数组
        Season[] seasons = Season.values();
        for (Season s:seasons) {
            System.out.println(s);//   1. toString();
        }
//    5.  valuesOf();用实参传入的字符串,到枚举类中查找有没有叫这个名字的对象,如果有就返回这个对象,没有就报错
        Season s2 = Season.valueOf("SPRING");
        System.out.println(s2.getName());
//    6. compareTo();将两个枚举常量对象的编号相减
        System.out.println(Season.SUMMER.compareTo(Season.AUTUMN));

    }
}
enum Season{//自定义枚举类
    //内部直接创建对象且static final修饰
    SPRING("春天","温暖"),SUMMER("夏天","炎热"),WINTER("秋天","凉爽"),AUTUMN("冬天","寒冷");
    private String name;
    private String climate;
    private Season(String name, String climate) {//构造器私有化
        this.name = name;
        this.climate = climate;
    }
    public String getName() {
        return name;
    }
    public String getClimate() {
        return climate;
    }
    @Override
    public String toString() {
        return "Season{" +
                "name='" + name + '\'' +
                ", climate='" + climate + '\'' +
                '}';
    }
}

输出结果:
SUMMER
1
Season{name=‘春天’, climate=‘温暖’}
Season{name=‘夏天’, climate=‘炎热’}
Season{name=‘秋天’, climate=‘凉爽’}
Season{name=‘冬天’, climate=‘寒冷’}
春天
-2

注意点:比如Season枚举类内部的常量对象是从0开始编号的

枚举练习

1.定义week枚举类,其中有周一至周天的定义:
Monday,Tuesday , Wednesday ,Thursday, Friday , Saturday , Sunday
2. 使用方法汇合成一个数组,且输出:星期一至星期日的字样

public class Test1 {
    public static void main(String[] args) {
    week[] weeks = week.values();
        for (week w:weeks) {
            System.out.println(w);
        }
    }
}
enum week{
    MONDAY("星期一"),TUESDAY("星期二"),WEDNESDAY("星期三"),THURSDAY("星期四"),
    FRIDAY("星期五"),SATURDAY("星期六"),SUNDAY("星期日");
    private String name;
    private week(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return this.name;
    }
}

运行结果:
星期一
星期二
星期三
星期四
星期五
星期六
星期日

枚举注意事项

  • 使用enum关键字定义的枚举,不能继承其他类。

因为使用enum关键字定义的枚举,会默认自动继承enum类。而java是单继承,不允许多继承

  • 枚举和普通类一样,可以实现接口,不管是自定义的枚举还是使用enum关键字定义的枚举

枚举实现接口语法:enum 枚举名 implement 接口名{}