定義
在某些情況下,一個類的對象是有限而且固定的,比如季節類,它只有4個對象;再比如行星類,目前只有8個對象。這種實例有限而且固定的類,在Java裏被稱爲枚舉類。
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修飾;如果強制指定訪問控制符,則只能指定private修飾符
- 枚舉類的所有實例必須在枚舉類的第一行顯示列出,否則這個枚舉類永遠都不能產生實例。列出這些實例時,系統會自動添加public static final修飾,無序程序員顯示添加。
定義枚舉類是,需要顯式列出所有的枚舉值,如下面代碼實例所示,所以的枚舉值時間以英文逗號(,)隔開,枚舉值列舉結束後以英文分號作爲結束。這些枚舉值代表了該枚舉類的所有可能的實例。
public enum SeasonEnum {
//在第一行列出4個枚舉實例
SPRING,SUMMER,FALL,WINTER
}
枚舉類實例
EnumTest
public class EnumTest {
public void judge(SeasonEnum s) {
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) {
for (SeasonEnum s : SeasonEnum.values()){
System.out.println(s);
}
new EnumTest().judge(SeasonEnum.SPRING);
}
}
運行結果
枚舉類的成員變量、方法和構造器
實例變量
Gender
public enum Gender {
MALE,FEMALE;
//定義一個public修飾的實例變量
public String name;
}
GenderTest
public class GenderTest {
public static void main(String[] args) {
Gender gender = Enum.valueOf(Gender.class, "FEMALE");
gender.name="女";
System.out.println(gender+"代表"+gender.name);
}
}
運行結果
枚舉類的實例只能是枚舉值,而不是隨意地通過new來創建枚舉類對象。
Java應該把所以設計成良好封裝的類,所以不應該允許直接訪問Gender類的name成員變量,而是應該通過方法來控制對name的訪問。否則可能出現很混亂的情形。
對上面代碼進行改進
Gender
public enum Gender {
MALE("男"),FEMALE("女");
private final String name;
Gender(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
GenderTest
public class GenderTest {
public static void main(String[] args) {
System.out.println(Gender.FEMALE.getName());
}
}
運行結果
實現接口的枚舉類
枚舉類也可以實現一個或多個接口。
代碼舉例說明
GenderDesc
public interface GenderDesc {
void info();
}
Gender
public enum Gender implements GenderDesc {
MALE("男"){
@Override
public void info() {
System.out.println("這個枚舉值代表男性!");
}
},
FENALW("女"){
@Override
public void info() {
System.out.println("這個枚舉值代表女性!");
}
};
Gender(String name) {
this.name = name;
}
private final String name;
public String getName() {
return name;
}
public static void main(String[] args) {
Gender.FENALW.info();
}
}
運行結果
包含抽象方法的枚舉類
演示代碼
Operation
public enum Operation {
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;
}
};
//抽象方法
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(4, 1));
System.out.println(Operation.TIMES.eval(3, 4));
System.out.println(Operation.DIVIDE.eval(4, 2));
}
}
運行結果
說明:枚舉類裏定義抽象方法時不能使用abstract關鍵字將枚舉類定義成抽象類(因爲系統自動會爲它添加abstract關鍵字),但因爲枚舉類需要顯示創建枚舉值,而不是作爲父類,所以定義的每個枚舉值時必須爲抽象方法提供實現,否則出現編譯錯誤。