在某些情况下一个类的对象是有限而且固定的,比如一个季节类的对象只能是春夏秋冬。这种实例有限而且固定的类,在java里被称为枚举类。
在早期代码当中,可能会直接通过简单的静态常量来表示枚举。
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;
这种定义方法简单明了,但存在如下几个问题。
但枚举又确实有存在的意义,因此早期也可而采用定义类的方式来实现,可以采用如下设计方式。
但通过定义类来实现枚举的代码量比较大,实现起来也比较麻烦。
java可以通过enum关键字(它与class interface关机词的地位相同),用以定义枚举类。正如之前所说,枚举类是一种特殊类,他一样可以拥有自己的成员变量、方法,可以实现一个或者多个的接口,可以定义自己的构造器。一个Java源文件中最多只能定义一个public访问权限的枚举类,且该java源文件也必须和该枚举类的类名相同。
但是枚举类并不是普通类,他和普通类有如下区别。
枚举类默认提供了一个values()方法,该方法可以很方便地变量所有的枚举值。
下面程序定义了一个SeasonEnum枚举类。
public enum SeasonEnum{
SPRING,SUMMER,FALL,WINNER;
}
变比上述程序,将会生成一个SeasonEnum.class文件,这表明枚举类是一种特殊的Java类。由此可见,enum关键词与class,interface关键词的作用大致相似。
所有的枚举类都继承自java.lang.Enum类,所以枚举类可以直接使用java.lang.Enum类所包含的方法。Java.lang.enum提供了以下方法。
枚举类也是一种类,只是它是一种比较特殊的类,因此它一样可以定义成员变量、方法和构造器。
publci enum Gender
{
MALE,FEMAL;
public String name;
}
上面枚举类里定义了一个名为name的实例变量,并且将它定义为一个public访问权限。下面将会通过如下程序使用该枚举类
public class GenderTest{
public static void main(String[] args){
Gender g = Enum.valueOf(Gender.class, "FEMALE");
g.name="女";
System.out.println(g+"代表:" + g.name);
}
}
上述程序说明使用枚举类与使用普通类并没有太大的区别。
枚举类也可以实现一个或者多个接口。与普通类实现一个或者多个接口完全一样,枚举类实现一个或者多个接口时,也需要实现该接口所包含的方法。
如果枚举类来实现接口里的方法,则每个枚举值在调用该方法时都有相同的行为方式(因为方法体完全一样。)如果需要每个枚举值在调用该方法时呈现出不同的实现方式,从而让不同的枚举值调用该方法时具有不同的行为方式。
public enum Gender implement GenderDesc{
MALE("男"){
public void info(){
System.out.println("这个枚举值代表男性");
}
}
FEMALE("女"){
public void info(){
System.out.println("这个枚举值代表女性");
}
}
}
上述代码看起来有点奇怪: 当创建MALE和FEMALE两个枚举值时,后面又紧跟了一堆花括号,这对花括号里包含了一个info方法定义。花括号部分实际上就是一个类体部分,在这种情况下,当创建MALE和FEMALE枚举值时,并不是直接创建Gender枚举值的实例,而是创建了Gender类的匿名子类的实例。因为粗体字括号部分实际上时匿名内部类的类体部分,所以这个部分的代码实际上是匿名内部类的类体部分,所以这个部分的代码语法与前面介绍的匿名内部类语法大致相似,只是他依然是枚举类的匿名内部子类。
并不是所有的枚举类都是用final修饰!非抽象的枚举类才默认使用final修饰。对于一个抽象类的枚举类而言——只要它包含了抽象方法,他就是抽象枚举类,系统就会默认使用abstract修饰,而不是使用final修饰。
编译上面的程序可以看到生成了Gender.class、Gender$1.class和Gender$2.class三个文件,这样的三个class文件正好证明了上面的结论:MALE和FEMALE实际上是Gender匿名子类的实例,而不是Gender类的实例。当调用MALE和FEMALE两个枚举值的方法时,就会看到两个枚举值的方法实现不同的行为方式。