为什么要用枚举:
枚举就是要让某个类型的变量的取值只能在若干个固定的值中的一个,否则,编译器会自动报错。枚举可以让编译器在编译的时候就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。
枚举几要素:
1、关键词
Java中枚举类型的关键词为enum与其他语言一样。凡是有关键字enum修辞定义的类型均是枚举类型。如:public enum TestEnum{test1,test2;}
2、级别
枚举类型的级别属于对象级别。它与类、接口是同一级别的,与类和接口的定义一样。所以枚举类型是一个总称,需要通过关键字enum去定义。且每定义一个枚举类型都会自动继承Java.lang.Enum。
3、实例
枚举类型不能外部实例。故所有枚举构造函数都是私有的或保护类型的。枚举类型的双重实例,第一重为系统实例,二重实例为代码内实例。系统实例是根据枚举量的数量自动实例对象并依次分配给枚举量的。代码内实例与类实例一样。
4、枚举量
前面讲了枚举量是枚举类型的一个实例,故每个枚举量都拥有其父类及其本枚举定义的字段和方法。
4.1枚举量的声明
枚举量的声明必须位于枚举定义体的开头。声明的方式为,枚举名加枚举构造参数。如枚举无构造参数的可省略为只用其名声明。如public enum Test{
test1(12),test2(23);
private Test(int i){}
}
5、枚举实用方法
Enum 重写了toString()方法,在定义枚举类型时如果不重写父类的toString(),则每个枚举变量得toString()将输出枚举变量名。
values(),返回所有枚举量。
ordinal(),返回枚举量的序号。
valueOf(),将String转换成枚举。
6、用途
枚举的出现是为了方便定义和使用一些常量字段。试图通过一个变量的方式引用所有字段,这既便于传递和全局化,也实现了集中管理。但,由于面向对象的编程语言的出现,使实现类似的功能变得非常简单,所以在面向对象的编程中,枚举的意义并没有在其在过程语言中那么重要。从枚举出现的意义上看,在面向对象的编程语言中,其用途不大,唯一的用途就是可以简化编程。
7、替代
使用具有常量字段的私有类可替换枚举类型。但要有批处理和模糊处理功能
了解了这些基本特性,我们来看看如何使用它们。
7个常用的用法:
用法一:常量
在JDK1.5之前,我们定义常量都是:publicstaticfianl....。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。
- public enum Color {
- RED, GREEN, BLANK, YELLOW
- }
用法二:switch
JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。
- enum Signal {
- GREEN, YELLOW, RED
- }
- public class TrafficLight {
- Signal color = Signal.RED;
- public void change() {
- switch (color) {
- case RED:
- color = Signal.GREEN;
- break;
- case YELLOW:
- color = Signal.RED;
- break;
- case GREEN:
- color = Signal.YELLOW;
- break;
- }
- }
- }
用法三:向枚举中添加新方法
如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且Java要求必须先定义enum实例。
- public enum Color {
- RED("红色", 1), GREEN("绿色",2), BLANK("白色",3), YELLO("黄色",4);
- // 成员变量
- private String name;
- private int index;
- // 构造方法
- private Color(String name, int index) {
- this.name = name;
- this.index = index;
- }
- // 普通方法
- public static String getName(int index) {
- for (Color c : Color.values()) {
- if (c.getIndex() == index) {
- return c.name;
- }
- }
- return null;
- }
- // get set 方法
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getIndex() {
- return index;
- }
- public void setIndex(int index) {
- this.index = index;
- }
- }
用法四:覆盖枚举的方法
下面给出一个toString()方法覆盖的例子。
- public enum Color {
- RED("红色", 1), GREEN("绿色",2), BLANK("白色",3), YELLO("黄色",4);
- // 成员变量
- private String name;
- private int index;
- // 构造方法
- private Color(String name, int index) {
- this.name = name;
- this.index = index;
- }
- //覆盖方法
- @Override
- public String toString() {
- return this.index+"_"+this.name;
- }
- }
用法五:实现接口
所有的枚举都继承自java.lang.Enum类。由于Java不支持多继承,所以枚举对象不能再继承其他类。
- public interface Behaviour {
- void print();
- String getInfo();
- }
- public enum Colorimplements Behaviour{
- RED("红色", 1), GREEN("绿色",2), BLANK("白色",3), YELLO("黄色",4);
- // 成员变量
- private String name;
- private int index;
- // 构造方法
- private Color(String name, int index) {
- this.name = name;
- this.index = index;
- }
- //接口方法
- @Override
- public String getInfo() {
- return this.name;
- }
- //接口方法
- @Override
- public void print() {
- System.out.println(this.index+":"+this.name);
- }
- }
用法六:使用接口组织枚举
- public interface Food {
- enum Coffee implements Food{
- BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO
- }
- enum Dessert implements Food{
- FRUIT, CAKE, GELATO
- }
- }
用法七:关于枚举集合的使用
java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的key是enum类型,而value则可以是任意类型。
还有一种比较复杂的枚举(带上抽象方法):
public enum TrafficLamp{
RED{
public TrafficLamp nextLamp(){
return Green;
}
},
Green{
public TrafficLamp nextLamp(){
return Yellow;
}
},
Yellow{
public TrafficLamp nextLamp(){
return RED;
}
},
public abstract TrafficLamp nextLamp();//abstract方法
}
其中每个枚举对象都是一个子类。