枚举


为什么要有枚举

  • 问题:要定义星期几或性别的变量,该怎么定义?假设用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()
	{
		@Override
		public WeekDay2 nextDay()
		{

			return MON;
		}

	};
	public final static WeekDay2 MON = new WeekDay2()
	{
		@Override
		public 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;}
	}

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

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

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


发布了25 篇原创文章 · 获赞 21 · 访问量 11万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章