目錄
- 1. 列舉概述
- 2. 列舉型別的定義
- 2.1 自定義列舉類
- 2.2 使用enum定義列舉
- 3. 列舉的隱含直接父類:Enum類
- 3.1 Enum類的主要方法
- 4. 列舉實作介面
1. 列舉概述
列舉:列舉,一個一個地列出來,
Java列舉:把某個型別的物件,全部列出來,
- 什么情況下會用到列舉型別?
某些類的物件只有確定的有限個時,可以把這樣的類宣告為列舉,
例如:
星期:Monday(星期一)......Sunday(星期天)
性別:Male(男)、Female(女)
月份:January(1月)......December(12月)
季節:Spring(春天)......Winter(冬天)
- 列舉是一種特殊的類,特殊在它的物件是有限的幾個常量物件,它既是一種類(class)型別卻又比型別別多了些特殊的約束,列舉的本質是一種受限制的類,
當需要定義一組常量時,可以使用列舉,
2. 列舉型別的定義
列舉是JDK1.5新增的參考資料型別,
-
列舉的物件的屬性不應允許被改動,所以應該使用 private final 修飾
屬性應該在構造器中為其賦值
若列舉顯式的定義了帶引數的構造器,則在列出列舉值時也必須對應地傳入引數
-
列舉的實作:
- jdk1.5之前,自定義列舉類
- jdk1.5,可以使用
enum關鍵字定義列舉
2.1 自定義列舉類
- 要求:
- 私有化類的構造器,保證不能在類的外部創建其物件
- 在類的內部創建列舉類的實體,并用宣告為
public static final的變數來參考 - 物件如果有實體變數,應該宣告為private final,并在構造器中初始化
class Season {
//宣告Season物件的屬性:使用 private final 修飾
private final String seasonName;
private final String seasonDesc;
//私有化Season類的構造器,并給物件屬性賦值
private Season(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
//在類的內部創建當前列舉類的物件,變數用 public static final 修飾
//public:外部可以使用列舉類的實體
//static:外部可以使用“類名.物件名”呼叫
//final:修飾的變數只能指向一個物件,保存的地址值不能更改
public static final Season SPRING = new Season("春天", "春暖花開");
public static final Season SUMMER = new Season("夏天", "烈日炎炎");
public static final Season AUTUMN = new Season("秋天", "秋高氣爽");
public static final Season WINTER = new Season("冬天", "白雪皚皚");
//其他需求
//獲取列舉類的物件的屬性
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
//提供toString()
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}
}
public class SeasonTest {
public static void main(String[] args) {
Season spring = Season.SPRING;
System.out.println(spring.getSeasonName());
System.out.println(spring);
}
}
2.2 使用enum定義列舉
jdk1.5之前,列舉的定義格式太繁瑣,存在很多重復代碼
使用 enum 關鍵字簡化列舉的定義
-
宣告格式:
[修飾符] enmu 列舉名{ //實體串列 //其他成員串列 }
列舉的所有實體必須在其他成員的前面顯式列出(多個實體之間 , 分隔 ; 結尾,只存在實體串列時,最后一個實體后面的 ; 可省略,存在其他成員時,不能省略),它們實際上都是 public static final 修飾的常量物件,不用自己添加修飾符,填上反而會報錯,
列舉的所有構造器只能使用 private 訪問控制符,并且是隱式私有的,
switch 運算式的case 子句可以直接使用 Enum定義的列舉的物件的名字,
如果列舉中只有一個物件,則可以作為單例模式的一種實作方式,
//RED、GREEN、BLUE不是列舉Color的屬性,而是它的物件
enum Color {
//只有物件串列,可省略最后一個物件后的;
//物件后面沒有“(引數串列)”就是呼叫無參構造
RED, GREEN, BLUE
}
//SPRING、SUMMER、AUTUMN、WINTER就是列舉Season的物件
enum Season {
//物件串列必須寫在類的前面,多個物件之間用,隔開,末尾物件;結束
//物件后面有“(引數串列)”就是呼叫有參構造
SPRING("春天", "春暖花開"),
SUMMER("夏天", "烈日炎炎"),
AUTUMN("秋天", "秋高氣爽"),
WINTER("冬天", "白雪皚皚");
//宣告Season物件的屬性:使用 private final 修飾
private final String seasonDesc;
private final String seasonName;
//私有化Season類的構造器,并給物件屬性賦值
private Season(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
//其他需求
//獲取列舉的物件的屬性
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
//一般不用重寫toString
}
public class SeasonTest {
public static void main(String[] args) {
Color blue = Color.BLUE;
System.out.println(blue); //BLUE
System.out.println(Color.class.getSuperclass()); //class java.lang.Enum
Season summer = Season.SUMMER;
System.out.println(summer); //SUMMER
System.out.println(Season.class.getSuperclass()); //class java.lang.Enum
Season s = Season.SPRING;
switch(s) {
case SPRING:
System.out.println("春暖花開");
break;
case SUMMER:
System.out.println("烈日炎炎");
break;
case AUTUMN:
System.out.println("秋高氣爽");
break;
case WINTER:
System.out.println("白雪皚皚");
break;
}
}
}
3. 列舉的隱含直接父類:Enum類
列舉不能繼承其他型別,因為列舉型別有一個隱含的直接父類 java.lang.Enum :它是所有列舉的父類,
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {...}
Enum類中有一個唯一的構造器:protected Enum(String name, int ordinal)
這個構造器不是程式員手動呼叫的,是編譯器自動呼叫,在所有列舉型別的構造器的首行,并且自動傳入name和ordinal的值,
name:就是列舉物件名稱
ordinal:就是列舉物件的序號(在列舉宣告中的位置),其中初始常量序號為0
3.1 Enum類的主要方法
除了toString方法,都是final修飾的方法,因此都不能重寫,
toString():回傳此列舉常量的名稱,與其在列舉宣告中的宣告完全相同
String name():回傳此列舉常量的名稱,與其在列舉宣告中的宣告完全相同,一般用toString()
int ordinal():回傳此列舉常量的序號(在列舉宣告中的位置),其中初始常量序號為0
- API中沒有的方法,是編譯器幫我們生成的方法:
values()方法:回傳列舉型別的物件陣列,該方法可以很方便地遍歷所有的列舉值,
valueOf(String str):根據列舉常量的名稱回傳對應的列舉物件,要求字串必須是列舉物件的“名字”,如不是,會有運行時例外
//便利列舉的物件
Season[] seasons = Season.values();
for (Season season : seasons) {
System.out.println(season);
}
//SPRING
//SUMMER
//AUTUMN
//WINTER
Season spring = Season.valueOf("SPRING");
System.out.println(spring); //SPRING
4. 列舉實作介面
和普通 Java 類一樣,列舉也可以實作一個或多個介面,
若每個列舉值在呼叫實作的介面方法呈現相同的行為,則只要統一實作該方法即可,
若需要每個列舉值在呼叫實作的介面方法呈現出不同的行為,則可以讓每個列舉值分別來實作該方法,
定義介面:
interface MyInter {
void message();
}
interface Info {
void show();
}
列舉實作介面:
enum Season implements MyInter, Info {
SPRING("春天", "春暖花開") {
@Override
public void show() {
System.out.println("春天在哪里");
}
},
SUMMER("夏天", "烈日炎炎") {
@Override
public void show() {
System.out.println("夏天的風");
}
},
AUTUMN("秋天", "秋高氣爽") {
@Override
public void show() {
System.out.println("秋天不回來");
}
},
WINTER("冬天", "白雪皚皚") {
@Override
public void show() {
System.out.println("大約在冬季");
}
};
private final String seasonDesc;
private final String seasonName;
private Season(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
//統一實作的重寫方法
@Override
public void message() {
System.out.println("一年四季各不同");
}
}
測驗類:
public class SeasonTest {
public static void main(String[] args) {
Season spring = Season.SPRING;
spring.message();
Season summer = Season.SUMMER;
summer.message();
Season autumn = Season.AUTUMN;
autumn.show();
Season winter = Season.WINTER;
winter.show();
}
}
一年四季各不同
一年四季各不同
秋天不回來
大約在冬季
對于同一個方法,兩種重寫方式可任選其一,也可同時存在,分別重寫時,所有的實體都要自己重寫介面中的方法,否則必須添加列舉的統一重寫方法,同時存在時,實體自己的重寫方法會覆寫列舉的統一重寫方法,
列舉既可以包含具體方法,也可以包含抽象方法, 如果列舉含有抽象方法,則列舉的每個實體都必須分別實作該方法,與實作介面類似,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/49419.html
標籤:Java
