Enum(列舉類)
阿新 • • 發佈:2021-08-01
Enum(列舉類)
什麼情況下使用列舉類?
有的時候一個類的物件是有限且固定的,這種情況下我們使用列舉類就比較方便?
為什麼不用靜態常量來替代列舉類呢?
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;
列舉類更加直觀,型別安全。使用常量會有以下幾個缺陷:
-
型別不安全。若一個方法中要求傳入季節這個引數,用常量的話,形參就是int型別,開發者傳入任意型別的int型別值就行,但是如果是列舉型別的話,就只能傳入列舉類中包含的物件。
-
沒有名稱空間。開發者要在命名的時候以SEASON_開頭,這樣另外一個開發者再看這段程式碼的時候,才知道這四個常量分別代表季節。
列舉類入門
-
簡單的列舉類
package enumcase; public enum SeasonEnum { SPRING,SUMMER,FALL,WINTER; }
- enum和class、interface的地位一樣
- 使用enum定義的列舉類預設繼承了java.lang.Enum,而不是繼承Object類。列舉類可以實現一個或多個介面。
- 列舉類的所有例項都必須放在第一行展示,不需使用new 關鍵字,不需顯式呼叫構造器。自動新增public static final修飾。
- 使用enum定義、非抽象的列舉類預設使用final修飾,不可以被繼承。
- 列舉類的構造器只能是私有的。
列舉類介紹
-
列舉類內也可以定義屬性和方法,可是是靜態的和非靜態的。
package enumcase; public enum SeasonEnum { SPRING("春天"),SUMMER("夏天"),FALL("秋天"),WINTER("冬天"); private final String name; private SeasonEnum(String name) { this.name = name; } public String getName() { return name; } }
- 實際上在第一行寫列舉類例項的時候,預設是呼叫了構造器的,所以此處需要傳入引數,因為沒有顯式申明無參構造器,只能呼叫有引數的構造器。
- 構造器需定義成私有的,這樣就不能在別處申明此類的物件了。列舉類通常應該設計成不可變類,它的Field不應該被改變,這樣會更安全,而且程式碼更加簡潔。所以我們將Field用private final修飾。
列舉類實現介面
-
列舉類可以實現一個或多個介面。與普通類一樣,實現介面的時候需要實現介面中定義的所有方法,若沒有完全實現,那這個列舉類就是抽象的,只是不需顯式加上abstract修飾,系統化會預設加上。
package enumcase; 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; } }; /** * 抽象方法,由不同的列舉值提供不同的實現。 * @param x * @param y * @return */ public abstract double eval(double x, double y); public static void main(String[] args) { System.out.println(Operation.PLUS.eval(10, 2)); System.out.println(Operation.MINUS.eval(10, 2)); System.out.println(Operation.TIMES.eval(10, 2)); System.out.println(Operation.DIVIDE.eval(10, 2)); } }
-
Operation類實際上是抽象的,不可以建立列舉值,所以此處在申明列舉值的時候,都實現了抽象方法,這其實是匿名內部類的實現,花括號部分是一個類體。我們可以看下編譯以後的檔案。
-
共生成了五個class檔案,這樣就證明了PLUS,MINUS,TIMES,DIVIDE是Operation的匿名內部類的例項。
-
switch語句裡的表示式可以是列舉值
-
Java5新增了enum關鍵字,同時擴充套件了switch。
public class SeasonTest { 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) { SeasonEnum s = SeasonEnum.SPRING; SeasonTest test = new SeasonTest(); test.judge(s); } }
-
case表示式中直接寫入列舉值,不需加入列舉類作為限定。