Java之枚舉類

一、枚舉類的概念

在某些情況下,一個類的對象是有限且固定的,比如季節類,它只有4個對象;再比如性別類,它只有兩個對象。這種實例有限且固定的類,在Java中被稱爲枚舉類。

枚舉類實際上是一種特殊的類,它由關鍵字enum定義(與class、interface關鍵字地位相同),可以有自己的Field、方法、可以實現一個或者多個接口,也可以定義自己的構造器(只能是私有的)。

一個Java源文件中最多隻能定義一個public訪問權限的枚舉類,且該Java源文件也必須和該枚舉類的類名相同,編譯之後會生成同名的class文件。

二、枚舉類與普通類的區別

  • 枚舉類可以實現一個或多個接口,使用enum定義的枚舉類默認繼承了java.lang.Enum類,而不是繼承Object類。
  • 使用enum定義、非抽象的枚舉類默認會使用final修飾 ,因此枚舉類不能派生子類。
  • 枚舉類的構造器只能使用private訪問控制符,如果省略了構造器的訪問控制符,則默認使用private修飾;如果強制指定訪問控制符,則只能指定private修飾符。
  • 枚舉類的所有實例必須在枚舉類的第一行顯式列出,否則這個枚舉類永遠都不能產生實例。列出這些實例時,系統會自動添加public static final修飾,無須程序員顯式添加。
public enum Season{
    //在第一行列出4個枚舉實例,以,分隔
    SPRING,SUMMER,FALL,WINTER;	//靜態常量一般大寫
}

三、在switch中使用枚舉類

如果需要使用某個枚舉類的某個實例,則可使用EnumClass.variable的形式,但在switch中可以直接使用枚舉值

public class EnumClass{
    public void judge(Season s){
		//switch語句裏的表達式可以是枚舉值
        switch(s){
            case SPRING : System.out.println("春天");break; 
            case SUMMER : System.out.println("夏天");break;
            case SUMMER : System.out.println("秋天");break;
            case SUMMER : System.out.println("冬天");
        }
    }
    
    public static void main(String[] args){
        for(Season s : Season.values()){
            System.out.println(s);	//可以直接打印枚舉值
        }
        //平常使用枚舉實例時
        //總是通過EnumClass.variable的形式來訪問
        new EnumClass().judge(Season.SPRING);
    }
}

該類通過values方法返回了Season枚舉類的所有實例,並通過循環迭代輸出了Season枚舉類 的所有實例。

四、枚舉類的Field、方法和構造器(不常用)

枚舉類也是一種類,只是它是一種比較特殊的類,因此它一樣可以定義Field、方法。只不過枚舉類通常會被設計爲不可變類,所以,我們應該將枚舉類的Field都使用private final修飾,這樣代碼更安全且簡潔。

public enum Gender{
	//此處的枚舉值必須調用對應的構造器來創建
    //如果沒有無參構造器,列出枚舉值是就必須傳入參數
    MALE("男"),FEMALE("女");
    private final String name;
    
    //枚舉類的構造器只能使用private修飾,默認也是private
    private Gender(String name){
        this.name = name;
    }
    
    public String getName(){
        return this.name;
    }
}

從此例可知,在枚舉類中列出枚舉值時,實際上就是調用構造器創建枚舉類對象,只是這裏無須使用new關鍵字,也無須顯式調用構造器。上面那個Season中列出枚舉值時無須傳入參數,甚至無須使用括號,是因爲其中包含默認的無參構造器。

五、實現接口的枚舉類(不常用)

枚舉類也可以實現一個或多個接口

public interface GenderDesc{
    void showInfo();
}
public enum Gender implements GenderDesc{
	//其他部分與四中的Gender一樣
    ...
   	//實現接口中的showInfo方法
    public void showInfo(){
        System.out.println("枚舉類");
    }
}

如果由枚舉類來實現接口裏的方法,每個枚舉值在調用該方法時都有相同的行爲方式(因爲方法體一樣)。如果需要每個枚舉值在調用該方法時呈現不同的行爲方式時,可以在*公共實現方法中使用switch(this)*做判斷或者每個實例分別實現該方法。

注: switch(this)比較推薦,因爲實例多的情況,沒開寫代碼冗餘太高。實例少的情況,推薦分開實現

public enum Gender implements GenderDesc{
    //此處的枚舉值必須調用對應的構造器來創建
    MALE("男"){	//花括號這是匿名內部類的寫法
    	public void showInfo(){
        	System.out.println("男性的枚舉方法");
    	}
    }
    
    FEMALE("女"){	
    	public void showInfo(){
        	System.out.println("女性的枚舉方法");
    	}
    }
}    

這裏就是分開實現,不推薦這種寫法,更推薦switch判斷

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章