枚舉類是一種特殊的類,它可以有自己的成員變量、方法。可以實現一個或者多個接口,也可以定義自己的構造器。一個java源文件中,最多隻能定義一個public訪問權限的枚舉類,且該java源文件也必須和該枚舉類名相同。
但是枚舉類終究不是普通的類,它和普通的類有以下區別:
- 枚舉類可以實現一個或者多個接口,使用enum定義的枚舉類默認繼承了Java.lang.Enum類,而不是默認繼承的Object類,因此枚舉類不能顯示繼承其他父類。其中Java.lang.Enum 類實現了java.lang.Serializable和java.lang.Compareble兩個接口。
- 使用enum定義。非抽象的枚舉類默認會使用final修飾。因此枚舉類不能派生子類。
- 枚舉類的構造器只能使用private訪問修飾符。
- 枚舉類的所有實例必須在枚舉類的第一行顯示列出,否者這個枚舉類永遠不會產生實例。列出實例時,系統會自動添加 public static final 修飾,無需程序員顯示添加。
枚舉類默認提供了一個 values()方法,該方法可以很方便的遍歷所有的枚舉值。
由於所有的enum定義的枚舉類默認繼承了Java.lang.Enum類,Java.lang.Enum提供了以下幾個方法:
- int compareTo(E e):該方法與指定的枚舉對象比較順序,同一個枚舉實例與相同的枚舉實例進行比較。如果該枚舉對象位於指定枚舉對象之前返回負整數,否者返回0.
- String name():返回次枚舉實例的名稱,這個名稱就是定義枚舉類列出的所有枚舉值之一。
- int ordinal():返回枚舉值在枚舉類中的索引。
- String toString():返回枚舉常量的名稱。(與name(),返回的是同一值)
- public static<T extends Enum<T>> T valueOf(Class<T> enumType,String name):返回指定枚舉中指定名稱的枚舉值。
枚舉類實現接口,與普通的類是一樣的,可實現一個或者多個接口。值得注意的是,如果由枚舉類來實現接口的話,則每個枚舉類調用該方法行爲方式都是一樣的。但是可以 讓每個枚舉類來實現該方法,從而實現了每個枚舉值調用該方法表現不同。
package Enum;
public enum FruitEnum implements GenderDesc {
Apple("紅色"){
public void info() {
System.out.println("我是蘋果");
}
},
Orange("橘色"){
public void info() {
System.out.println("我是橘子");
}
},
Banana("黃色"){
// public void info() {
// System.out.println("我是香蕉");
// }
},
Pineapple("橙色"){
// public void info() {
// System.out.println("我是菠蘿");
// }
};
private final String color;
private FruitEnum(String color) {
this.color = color;
}
public String getColoer() {
return color;
}
@Override
public void info() {
System.out.println("-------------------");
}
}
---------------------------------------我是分界線-----------------------------------
package Enum;
public class TestEnum {
public static void main(String[] args) {
for (FruitEnum e : FruitEnum.values()) {
System.out.println(e);
}
FruitEnum e = FruitEnum.Apple;
System.out.println(e.compareTo(FruitEnum.Orange));
System.out.println(e.compareTo(FruitEnum.Banana));
System.out.println(e.getColoer());
e.info();
FruitEnum.Banana.info();
FruitEnum.Pineapple.info();
}
}
輸出:
Apple
Orange
Banana
Pineapple
-1
-2
紅色
我是蘋果
-------------------
-------------------
查看bin目錄會發現,出現了FruitEnum$1.class,FruitEnum$2.class,FruitEnum$3.class,FruitEnum$4.class。其實這有點類似匿名內部類。枚舉值後面緊跟了一堆花括號,花括號的部分實際上就是一個類體部分。在這種情況下,當創建Apple,Orange
枚舉類的實例時,相當於創建了FruitEnum匿名子類的實例。但是前面提到過,枚舉類不是被final修飾嘛,怎麼還能派生子類呢?在bin目錄下,查看FruitEnum.class,可以發現此時,FruitEnum已經被 abstract修飾了。這意味着並不是所有的枚舉類被final修飾。對於一個枚舉類而言,只要它包含了抽象方法,它就是抽象枚舉類,系統會默認使用abstract修飾,而不是final。
包含抽樣方法的枚舉類:
package Enum;
public enum Operation {
ADD{
@Override
public double eval(double x, double y) {
return x + y;
}
},
MINUS{
@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.ADD.eval(2, 3));
System.out.println(Operation.MINUS.eval(2, 3));
}
}