6-Enum枚举类

枚举类基础

关键字 enum 用来定义枚举类,地位与 class、interface 相同。枚举类是一种特殊的类,它一样可以有自己的成员变量、方法,可以实现一个或多个接口,也可以定义自己的构造器。

但枚举类终究不是普通类,它与普通类有如下区别:

  • 枚举类默认继承了 java.lang.Enum 类,而不是 Object 类,因此枚举类不能显式继承其他父类。但可以实现一个或多个接口。
  • 使用 enum 定义、非抽象的枚举类默认会使用 final 修饰,因此枚举类不能派生子类。
  • 枚举类的构造器只能用 private 修饰。
  • 枚举类的所有实例必须在枚举类的第一行显式列出,否则这个枚举类永远不能产生实例。并且这些实例都默认使用 public static final 修饰的类变量来保持。
1
2
3
4
5
6
public enum SeasonEnum
{
//在第一行列出4个枚举 **实例**!!!
//每一个枚举值就是一个该枚举类的实例!!
SPRING,SUMMER,AUTUMN,WINTER;
}

当需要使用该枚举类的某个实例时,可使用 EnumClass.variable 的形式,例如 SeasonEnum.SPRING

枚举类默认有一个 values() 方法,可以返回该枚举类的所有实例:

1
2
3
4
for(SeasonEnum s:SeasonEnum.values())
{
System.out.println(s);
}

所有的枚举类都可以直接使用父类 java.lang.Enum 中提供的几个方法:

  • int compareTo(E o):该方法用于与指定枚举对象比较顺序,同一个枚举实例只能与相同类型的枚举实例进行比较。如果该枚举对象位于指定枚举对象之后,返回1;位于之前,返回-1;否则返回0。
  • String name():返回此枚举实例的名称
  • int ordinal():返回枚举值在枚举类中的索引值(即枚举值在枚举类声明中的位置,第一个枚举值的索引为 0);
  • String toString():返回枚举常量的名称
  • public static<T extends Enumn<T>> T valueOf(Class<T> enumType,String name):一个静态方法,用于返回指定枚举类中指定名称的枚举值。名称必须与在该枚举类中声明枚举值时所用的标识符完全匹配;

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

枚举类也是一个类,因此它一样可以定义成员变量、方法和构造器。

枚举类通常应该设计成不可变类,也就是说,它的成员变量不应该允许改变,这样会更安全,而且代码更简洁。因此建议将枚举类的成员变量都使用 private final 修饰。并且在构造器里为这些成员变量指定初始值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private enum Seanson
{
SPRING("春"), SUMMER("夏"), FALL("秋"), WINTER("冬");

private final String name;

private Seanson(String name)
{
this.name = name;
}

public String getName()
{
return this.name;
}
}

注意,枚举类在首次使用的时候就会通过构造器隐式全部构造出所有枚举实例!!!

实现接口的枚举类

枚举类也可以实现一个或多个接口,也需要实现该接口所包含的方法。如果需要每个枚举值在调用接口方法时呈现出不同的行为方式,则可以让每个枚举值分别去实现该接口方法,每个枚举值提供不同的实现方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
interface SeasonDesc
{
void info();
}

enum Season implements SeasonDesc
{
SPRING("春")
{
@Override
public void info()
{
System.out.println("春天来了");
}
},
SUMMER("夏")
{
@Override
public void info()
{
System.out.println("夏天来了");
}
},
FALL("秋")
{
@Override
public void info()
{
System.out.println("秋天来了");
}
},
WINTER("冬")
{
@Override
public void info()
{
System.out.println("冬天来了");
}
};

private String name;

private Season(String name)
{
this.name = name;
System.out.println(this.name);
}
}

包含抽象方法的枚举类

假设一个 Operation 枚举类,它的 4 个枚举值 PLUS、MINUS、TIMES、DIVIDE 分别代表 加、减、乘、除 4 种运算,该枚举类需要定义一个 eval() 方法来完成计算。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
private enum Operation
{
//为该枚举类定义一个抽象方法
public abstract double eval(double x, double y);

PLUS
{
@Override
public double eval(double x, double y)
{
return x + y;
}
},
MINUS
{
@Override
public double eval(double x, double y)
{
return x - y;
}
},
TIMES
{
@Override
public double eval(double x, double y)
{
return x * y;
}
},
DIVIDE
{
@Override
public double eval(double x, double y)
{
return x / y;
}
};
}