目錄
(四)面向對象:
12、枚舉類:
(1)概述:
(2)枚舉類的定義格式:
(3)編譯與反編譯:
(4)Enum類的特點:
(5)枚舉類的測試類以及一些特有的方法:
(四)面向對象:
12、枚舉類:
(1)概述:
?為什么要有枚舉類:
1、類型安全,String類的color傳入“1”也不會報錯,但其實無意義;而enum是強類型,只能使用預定義的值。
2、語意清晰,代碼可讀性高
3、限定取值范圍,避免非法值。? ?
????定義:是一種特殊得類,通過enum關鍵字定義。
(2)枚舉類的定義格式:
? ? ? ? 枚舉元素必須寫在第一行,如果有多個的話,用逗號','隔開,最后用分號';'結束 ,如果';'后面沒有其他內容的話,';'可以省略,但不建議省略????????
? ? ? ? 枚舉元素和枚舉元素()效果一樣,含義為:執行枚舉類默認構造器去實例化枚舉元素對象
Gender g1 = Gender.Male; //Male() : Male = new Gender();
? ? ? ? 枚舉元素本質上是枚舉類對象,由static與final修飾。
? ? ? ? ? ? ? ? [修飾符] 數據類型 數據成員名;
? ? ? ? ? ? ? ??[修飾符] 數據類型 數據成員方法(){……}
枚舉類可以由普通數據成員(方法與屬性)
? ? ? ? ? ? ? ? private 構造方法();
? ? ? ? ? ? ? ? private 構造方法(參數){……}
構造方法必須私有化
不自定義是,系統提供無參構造
枚舉元素那里如果調用,必須定義
? ? ? ? ? ? ? ?[修飾符] static 返回值 成員方法名(){……}
????????????????[修飾符] static 返回值 成員屬性名;
枚舉類中可以由靜態方法與屬性
}
以上是沒有抽象方法的枚舉類的定義格式,從上也可以看出,枚舉類中可以由普通成員,構造方法,靜態成員。
下面我們展示案例:
//枚舉類基本定義
enum Week {//枚舉元素必須寫在第一行,如果有多個的話,用逗號','隔開,//最后用分號';'結束//如果';'后面沒有其他內容的話,';'可以省略,但不建議省略MON, TUE, WED; //WED()//WED和WED()效果一樣,含義為:執行枚舉類默認構造器去實例化枚舉元素對象//源代碼類似:public static final Week WED = new Week();//注意:用戶沒有提供構造器,系統會提供默認的構造器 private Week(){}//枚舉類數據成員和成員方法,可以包含一個或多個private String desc;public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}//枚舉類構造方法,如果不提供,系統會提供默認構造方法,private修飾//如果用戶自定義枚舉類構造方法,則系統不再提供private Week2() {}//自定義枚舉方法,注意必須用private修飾private Week2(String desc) {this.desc = desc;}
}
接下來是含有抽象方法的枚舉類的定義:
[修飾符]? enum 枚舉類名{
? ? ? ? 枚舉元素1(根據構造方法傳實參){
? ? ? ? ? ? ? ? 重寫該類所有的抽象方法;
????????},枚舉元素2(根據構造方法傳實參){
? ? ? ? ? ? ? ? 重寫該類所有的抽象方法;
????????},……枚舉元素n(根據構造方法傳實參){
? ? ? ? ? ? ? ? 重寫該類所有的抽象方法;
????????};
理解:當我們定義了一個抽象方法,一般是有子類繼承后重寫,然后利用多態調用,但是我們的enum類是final修飾的類,無法被子類繼承,那如何來重寫抽象方法,這里我們想到了匿名內部類,我們可以在創建對象時通過匿名內部類來重寫抽象方法,那我們又想到了枚舉類的特殊性,創建的對象只能取預定義好的枚舉元素那不能再創建對象時寫匿名內部類,我們就只能在枚舉類中創建枚舉元素時,為枚舉元素寫匿名內部類。(枚舉類可以理解為在類內部預定義對象,類外創建的對象只能等于這些預定義對象,那可以理解為實際上枚舉元素就是對象。)
抽象方法不能私有,且每個枚舉元素都必須重寫所有的抽象方法。
? ? ? ? 抽象方法聲明;
}
案例展示:
enum Week3 {//注意:包含抽象方法的枚舉類是抽象類,不能直接實例化對象//所以定義枚舉類元素(所有)時候,一定要重寫抽象方法//注意:必須在所有的枚舉元素定義中,重寫所有抽象方法//MON {MON() {//在枚舉元素中重寫抽象方法@Overridepublic void show() {System.out.println("in show, MON: 周一");}}, TUE("星期二") {//注意,每個枚舉元素中都要重寫重寫方法,且要重寫所有的抽象方法@Overridepublic void show() {System.out.println("in show, TUE: " +this.getDesc());}};//枚舉類數據成員及get方法private String desc;public String getDesc() {return desc;}//枚舉類自定義構造方法private Week3() {}private Week3(String desc) {this.desc = desc;} //枚舉類 包含的 抽象方法(可以0或多個)public abstract void show();
}
(3)編譯與反編譯:
我們編寫的enum類是不完整的,有很代碼或者修飾符都被省略掉了
我們可以通過反編譯去查看源碼:
javap? enum類的字節碼文件
但是這樣獲得的源碼是隱藏了私有屬性與方法的,如果想查看,則需要使用命令
javap -p enum類的字節碼文件
從這里我們也可以看出來:
枚舉類Gender本質上是一個final修飾的類,不可以被繼承
枚舉類會默認繼承 java.lang.Enum 這個抽象泛型類
枚舉元素,本質上是枚舉類對象,且由 static和final 修飾
枚舉類提供私有構造器,我們在類外不能主動創建枚舉類對象
枚舉類中可以包含 public static 靜態方法
注意:包含抽象方法的enum類,不會被final修飾
(4)Enum類的特點:
<1>類由final修飾,不能被繼承,但是final會隱身,反編譯即可看到,包含抽象方法的enum類,不會被final修飾。
<2>枚舉元素由final與static修飾,唯一且不能被修改,由類名直接調用
<3>枚舉類設有非私有構造器,外界不能通過new創建對象
<4>可以包含靜態方法
(5)枚舉類的測試類以及一些特有的方法:
<1>對象的賦值只能是枚舉元素:Gender g1 = Gender.MALE;
<2>輸出枚舉對象,默認輸出枚舉元素
<3>獲取枚舉元素名字的方法:g.name();
<4>獲取枚舉元素編號:g.ordinal();(返回int型);