枚举

来源:互联网 发布:c语言编程书籍 编辑:程序博客网 时间:2024/06/15 16:11


为什么要有枚举

  • 问题:要定义星期几或性别的变量,该怎么定义?假设用1-7分别表示星期一星期日,但有人可能会写成int weekday =0
  • 枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。
用普通类如何实现枚举类的功能,定义一个Weekday的类来模拟枚举的功能。

  • 私有的构造方法
  • 每个元素分别用一个公有的静态成员变量表示
  • 可以有若干公有方法或抽象方法,例如,要提供nextDay方法必须是抽象的。

我们现在来思考这样的应用,每一个星期得到这个对象后都可以调用它的nextDay方法来得到下一天是星期几,先想到的是下面的代码:

为了演示方便我将星期定位两天。

package cn.itcast.day1;public  class CopyOfWeekDay1{private CopyOfWeekDay1(){}public final static CopyOfWeekDay1 SUN = new CopyOfWeekDay1();public final static CopyOfWeekDay1 MON = new CopyOfWeekDay1();public CopyOfWeekDay1 nextDay(){if (this == SUN){return MON;} else{return SUN;}}}

测试类如下:

package cn.itcast.day1;import java.util.Date;public class CopyOfEnumTest{public static void main(String[] args){CopyOfWeekDay1 weekDay = CopyOfWeekDay1.MON;System.out.println(weekDay.nextDay());}}
由于如果采用上面的方法构建枚举,nextDay会有大量的if{}else{}语句块,为了方便现在又该如下:

package cn.itcast.day1;public abstract class WeekDay2{private WeekDay2(){}public final static WeekDay2 SUN = new WeekDay2(){@Overridepublic WeekDay2 nextDay(){return MON;}};public final static WeekDay2 MON = new WeekDay2(){@Overridepublic WeekDay2 nextDay(){return SUN;}};public abstract WeekDay2 nextDay();public String toString(){return this == SUN ? "SUN" : "MON";}}

把该类定义为一个抽象类,公有的方法也定义为抽象的,接下来使用匿名内部类产生实例对象覆盖抽象方法。

总结:枚举是一种特殊的类,其中每个元素都是该类的一个实例对象,例如可以调用WeekDay.SUN.getClass().getName()和WeekDay.class.getName().

我们来这样定义一个枚举:

public enum WeekDay{SUN,MON,TUE,WED,THI,FRI,SAT}

我们可以使用枚举类给我们提供的方法:

WeekDay weekDay2 = WeekDay.FRI;System.out.println(weekDay2);System.out.println(weekDay2.name());System.out.println(weekDay2.ordinal());System.out.println(WeekDay.valueOf("SUN").toString());System.out.println(WeekDay.values().length);


我们在枚举类中定义的方法都必须放在元素列表之后,记住加;号。

我们可以实现带构造方法的枚举:

  • 构造方法必须定义成私有的
  • 如果有多个构造方法,如果有多个构造方法,该如何选择哪个构造方法?
  • 枚举元素MON和MON()的效果一样,都是调用默认的构造方法。

public enum WeekDay{SUN(1),MON(),TUE,WED,THI,FRI,SAT;private WeekDay(){System.out.println("first");}private WeekDay(int day){System.out.println("second");}}
实现带有抽象方法的枚举:


首先我们先定义如下:

public enum TrafficLamp{RED,GREEN,YELLOW;public abstract TrafficLamp nextLamp();}
然后实现方法,因为每一个元素就是一个该枚举类的实例对象,所以我们可以这样实现:

public enum TrafficLamp{RED(30){public  TrafficLamp nextLamp(){return GREEN;}},GREEN(45){public  TrafficLamp nextLamp(){return YELLOW;}},YELLOW(5){public  TrafficLamp nextLamp(){return RED;}};public abstract TrafficLamp nextLamp();private int time;private TrafficLamp(int time){this.time = time;}}

上面的枚举还分别为各种灯定义了时间。
枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。

枚举元素必须位于枚举体中最开始的部分,枚举元素列表的后面要有分号与其他成员分隔。

枚举只有一个成员时,就可以作为一种单例的实现方式。