JAVA枚举类型
一、Java枚举类型
1、枚举类型:就是将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用。
2、枚举类型是一种特殊类,并且具有自己的方法。编译后会产生相应的.java文件。
3、枚举类型里面的成员是枚举类型的static final实例(类似类的对象),称为枚举实例。
4、使用enum创建枚举类型,所有的enum都继承自java.lang.Enum类,而且enum可以添加方法,甚至覆盖Enum的方法,甚至可以有main()方法。但是有一点需要我们注意:enum不能继承enum。然而,enum可以同时实现一个或多个接口。
5、默认值序列值
//:enumerated/Num.java
enum Num{GROUND, CRAWLING, HANGIN, PACK}
枚举实例的默认赋值是从0开始,后一个枚举实例值是其前一个枚举实例值加1,即GROUND=0, CRAWLING=1, HANGIN=2, PACK=3。
6、显式序列值
//:enumerated/Num.java
enum Num{GROUND=3, CRAWLING, HANGIN=7, PACK}
CRAWLING的值为4,PACK的值为8。
7、静态导入枚举类型
在其他文件中使用到已存在的枚举类型,可以静态导入。例如:
//:enumerated/other.java
import static enumerated.Str.*;
二、向枚举类型中添加方法和添加枚举实例自身描述
为枚举实例添加自身描述,需要向枚举类型中添加一个描述字段、一个传入描述的构造器和返回该描述字段的方法。这样类似的功能在枚举类型中会大量应用。
与向类中添加成员方法没有什么区别。例如:红绿灯实例。
public enum Lamp {
RED("GREEN"),GREEN("YELLOW"),YELLOW("RED");
ptivate String enumdescri;
//构造器只能在内部使用,即使不声明为private也不会有任何变化
private Lamp(String descri){ enumdescri = descry;}
//获取枚举实例自身描述
public String getDescri(){return enumdescri;}
//根据描述获取相应枚举实例,这里的valueOf()方法由编译器添加static方法
public Lamp getNextLamp(){return valueOf(enumdescri);}
//重写toStirng()
public String toString(){
String id = name(); //获取枚举实例的名称,例如:RED
return id+":"+ ordinal()+", "+getDescri();
}
public static void main(String[] args){
Lamp lamp = Lamp.RED;
for(int i = 0; i < 1000; i++){
System.out.println(lamp);
lamp = lamp.getNextLamp();
}
}
}
三、枚举类型的神秘之处
这里说神秘是指:编译器向枚举类型添加一些static方法。例如:
1、values(),返回枚举实例的列表
2、valueOf(String),更加枚举实例的自身描述返回枚举实例
所以,使用Enum变量指向一个enum实例时,以上方法无法调用。
四、枚举类型与接口
1、枚举类型实现接口:与类实现接口没有任何区别。例如:
enum CartoonCharacter implements Generator< CartoonCharacter >{
SLAPPY, SPANKY, PUNCHY, SILLY, BOUNCY, NUTTY, BOB;
Private Random rand = new Random(47);
public CartoonCharacter next(){
return values()[rand.nextInt(values().length)];
}
}
//main
CartoonCharacter cc = CartoonCharacter.BOB;
for(int i = 0; i < 100; i++)
System.out.println(cc.next());
2、使用接口组织枚举
在一个接口内部,创建实现该接口的枚举,以此将元素进行分组,可以达到将枚举元素分类的目的。
interface Food{
enum Appetizer implements Food{
SALAD, SOUP, SPRING_ROLLS;
}
enum MainCourse implements Food{
LASAGNE, BURRITO, PAD_THAI, LENTILS;
}
enum Dessert implements Food{
TIRAMISU, GELATO, BLACK_FOREST_CAKE, FRUIT;
}
enum Coffee implements Food{
BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,TEA;
}
}
public enum Course{
APPETIZER(Food.MainCourse.class),
MAINCOUTSE(Food.MainCourse.class),
DESSERT(Food.Dessert.class),
COFFEE(Food.Coffee.class);
private Food[] values;
private Course(Class<? extends Food> kind){
values = kind.getEnumConstants();
}
public Food get(int i){return values[i];}
}
//main
for(Course course : Course.values())
for(int j = 0; j < 5; j++){
Food food = course.get(j);
System.out.prinln(food);
}
3、枚举嵌套枚举:管理枚举更好的办法
public enum Course{
APPETIZER(Food.MainCourse.class),
MAINCOUTSE(Food.MainCourse.class),
DESSERT(Food.Dessert.class),
COFFEE(Food.Coffee.class);
private Food[] values;
private Course(Class<? extends Food> kind){
values = kind.getEnumConstants();
}
public Food get(int i){return values[i];}
//嵌套枚举
public interface Food{
enum Appetizer implements Food{
SALAD, SOUP, SPRING_ROLLS;
}
enum MainCourse implements Food{
LASAGNE, BURRITO, PAD_THAI, LENTILS;
}
enum Dessert implements Food{
TIRAMISU, GELATO, BLACK_FOREST_CAKE, FRUIT;
}
enum Coffee implements Food{
BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,TEA;
}
}
}
五、Enum:枚举类型的公共基类
六、枚举规则集EnumSet
弥补enum不能添加或删除其实例的短板。EnumSet性能上比HashSet还高效快速。EnumSet的基础是long,而一个enum实例使用一位bit表示(开关),所以,EnumSet应当最大可以有64个enum实例。如果超过,EnumSet会再增加一个long。
七、枚举图EnumMap
EnumMap的key来自enum,是enum的一个实例。而EnumMap的value可以是与key对应的任何东西。
例如:下面演示了命令模式的使用
八、枚举实例方法
enum允许程序员为enum的实例编写方法,从而为每个enum实例赋予各自不同的行为。但是,需要注意的是:要实现实例的相关方法,必须要为enum定义一个或多个abstract方法,然后在实例中实现这些这些抽象方法。
|
|