您的位置:首页 > 职场人生

黑马程序员_张孝祥_Java基础加强_枚举类

2013-08-09 12:29 225 查看
----------- android培训java培训、期待与您交流! ------------

 

Java 5.0之前的枚举实现方法:

枚举是java 5 新特性。在java 5之前,并没有对枚举的直接支持。人们常常使用接口来存放枚举值。

这是因为接口有几个特点非常适合来设计枚举。

首先,接口无法创建对象。而用枚举,仅仅是要存储几个静态常量,不需要创建存放枚举值的类的实例,因此这点正符合枚举的需求。

其次,接口中的成员字段默认为public static final的,这点也正符合枚举的需求。

 

例子: 

用类来表示枚举:

public class WeekDay {
public static final int MONDAY = 1;
public static final int TUESDAY = 2;
public static final int WENSDAY = 3;
public static final int THURSDAY = 4;
public static final int FRIDAY = 5;
}


这样不但在声明时要声明为public static final,而且WeekDay类还可以被创建对象。

用接口来表示枚举:

public interface WeekDay{
int MONDAY = 1;
int TUESDAY = 2;
int WENSDAY = 3;
int THURSDAY = 4;
int FRIDAY = 5;
}


这样看起来简洁多了,但是依然有一些缺点:

首先,枚举值的类型是int,当然也可以设计成String,但是依然不是类型安全的。

其次,设计为了接口就不能包含可用方法了。

 

因为具有这些缺点,所以接口只能用来实现非常非常简陋的枚举功能。

 

要解决这些问题,还是要使用类:

public class WeekDay {
public static final WeekDay MONDAY = new WeekDay(1);
public static final WeekDay TUESDAY = new WeekDay(2);
public static final WeekDay WENSDAY = new WeekDay(3);
public static final WeekDay THURSDAY = new WeekDay(4);
public static final WeekDay FRIDAY = new WeekDay(5);
private int value;
private WeekDay(int i){
this.value = i;
}
public int getValue(){
return value;
}
}
这样就解决了类型安全问题,并且可通过==进行枚举值比较。

同时通过构造器私有化,组织了枚举类被实例化。

于此同时,每个枚举值都是WeekDay的实例对象,都具备了WeekDay中的方法。

 

然后有时候我们希望每个枚举值能有自己的方法,即WeekDay的方法对于每个枚举值有不同的行为。

这时候可以将枚举类为抽象类,将具有不同行为的方法定义为抽象方法,存储的枚举值为此抽象类的子类对象。

public abstract class WeekDay {
public static final WeekDay MONDAY = new WeekDay(1){
publicWeekDay nextDay(){
returnTUESDAY;
}
};
public static final WeekDay TUESDAY = new WeekDay(2){
publicWeekDay nextDay(){
returnMONDAY;
}
};
private int value;
private WeekDay(int i){
this.value = i;
}
public int getValue(){
return value;
}
public abstract WeekDay nextDay();
}


Java 5对枚举的支持:

 

在Java5中,添加了一个新特性,枚举。

定义枚举类时使用enum关键字,比如可以使用一下方法来设计一个简单的枚举类:

public enum WeekDay{
MONDAY, TUESDAY, WENSDAY, THURSDAY, FRIDAY; //最后这个“;”可写可不写。
}
这个WeekDay枚举类是java.lang.Enum类的一个子类,而其中的枚举值都是WeekDay的实例对象。

这个跟上面1.4版本的第一种枚举类类似,但是是类型安全的,并且代码要简洁得多。

同时,还可以向枚举类中添加构造器与方法,来达到上面1.4的第二种枚举类的效果:

public enum WeekDay{
MONDAY(1),TUESDAY(2), WENSDAY(3), THURSDAY(4), FRIDAY(5); //这里的;一定要写
privateint value;
privateWeekDay(int i){           //构造器必须是私有的
this.value= i;
}
public int getValue(){
return value;
}
}
这里与1.4的实现功能相似,但是更加简洁。并且,枚举类从Enum类中继承了大量实用方法,可以直接使用:

Class<E> getDeclaringClass() //返回与此枚举常量的枚举类型相对应的 Class 对象。

static <T extends Enum<T>>T  valueOf(Class<T> enumType,String name) //返回带指定名称的指定枚举类型的枚举常量。在具体枚举类中可以简单使用valueOf(String name)。

String toString()  //返回枚举常量的名称,在设计时可以覆盖此方法以获得更加友好的名称

String name()      //返回枚举常量的名称,与toString()行为近似,但是此方法是final的

 

int ordinal() //返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。

int compareTo(E o) //比较此枚举与指定对象的顺序,默认为声明顺序

boolean equals(Object other) //相等性比较,因为枚举值的单例性,因此可直接用==进行比较

int hashCode() 返回枚举常量的哈希码。

 

protected Object clone() //直接抛出CloneNotSupportedException,此方法是final的,因为不允许枚举对象被复制

protected void finalize() // 枚举类不能有 finalize 方法。

 

注意:

枚举类虽然是Enum类的子类,但是编译器不允许我们绕过enum关键字直接使用extends的方式来创建Enum类的子类对象,这样会出

现编译错误。同理,enum类也不能继承另一个enum类。

 

带有抽象方法和有参构造器的枚举类:

public enum WeekDay{
MONDAY(1){
publicWeekDay nextDay(){
returnTUESDAY;
}
},
TUESDAY(2){
publicWeekDay nextDay(){
returnMONDAY;
}
};//这里的;一定要写
privateint value;
privateWeekDay(int i){          //构造器必须是私有的
this.value= i;
}
public int getValue(){
return value;
}
publicabstract WeekDay nextDay();
}

当设计了一个带有抽象方法的枚举类时,其枚举值就不再是此枚举类的实例对象,而是此枚举类的子类对象。

另:枚举可以用来作为单例的一种实现方式,当枚举只有一个成员时,实际上就是单例。

----------- android培训java培训、期待与您交流! ------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息