Java 基础加强 - JDK1.5 新特性 - 枚举

Java JDK1.5新特性 – 枚举

一.枚举定义

定义:枚举是使用enum声明定义的特殊class,但是它并不继承自java.lang.Object类,它是继承自java.lang.Enum<E>这个类,这个类是所有 Java 语言枚举类型的公共基本类,其中java.lang.Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口。

二.  枚举的特点

1.     枚举既然是一个特殊的类,那么它也可以有构造方法,只不过枚举中的构造方法都是私有的,只有在内部创建枚举值(也可以说是这个枚举类型的对象)的时候才使用,绝对不允许有public构造器。这样可以保证外部代码无法新构造枚举类的实例,构造器可以有多个,调用哪个即初始化相应的值。(因为我们知道枚举值是public static final的常量而已。 但枚举类的方法和数据域可以允许外部)。

2.     每个元素(枚举值)都是public和static、final修饰的,也就是我们经常使用的常量定义方式,所以一般枚举值名称都是全部使用大写字母表示,可以用枚举类型名称直接调用,就跟普通类中的静态属性和方法一样,可以使用类名称.静态成员直接调用一样。

3.     枚举中枚举值只能在声明时给定,编译期之后或运行期是不能想普通类那样new对象的,所以枚举的元素是稳定且固定的,而且元素都是有限的。

4.     一般swtich只能使用byte、short、int、char四种基本数据类型作为值,但是枚举也可以作为switch语句的值使用。

5.    枚举类里定义抽象方法时,无需显示使用abstract关键字将枚举类定义成抽象类,但因为枚举类需要显示创建枚举值,而不是作为父类,所以定义每个枚举值时必须为抽象方法提供实现,否则将出项编译错误,通常是在内部使用匿名内部类实现方式比较方便。

6.    通过enum关键字定义枚举类,枚举类是一个特殊的类,每个元素都是该类的一个实例对象。

7.    如果调用者想打印枚举类中元素的信息,需由编写此类的人定义toString方法。

8.    枚举类是一个class,而且是一个不可被继承的final类,其中的元素都是类静态常量。

9.    枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。

10.   枚举元素必须位于枚举体中的最开始部分,枚举元素列表的后要有分号与其他成员分隔。把枚举中的成员方法或变量等放在枚举元素的前面,编译器报告错误。

三.为什么要使用枚举?

1.     假如现在有一个变量,要给它赋值,但是这个变量的取值只能为若干个固定值中的一个,否则编译就错误,减少运行时候的误差和错误,那么这个时候就要使用枚举,在枚举类中定义限定的几个可使用的枚举元素,这样就可以很安全和方便的给变量赋值了。

2.      在编译时期就会发现错误,表明值不符合,减少了运行时期的错误。

例如:

A.     要定义星期几或性别的变量,该怎么定义?假设用1-7分别表示星期一到星期日,但有人可能会写成int weekday = 0;或即使使用常量方式也无法阻止意外。

B.     枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。

练习代码1:

	/* 
	 * 用普通类如何实现枚举功能,定义一个Weekday的类来模拟枚举功能。  
	    1、私有的构造方法 
	    2、每个元素分别用一个公有的静态成员变量表示 
	    3、可以有若干公有方法或抽象方法。采用抽象方法定义nextDay就将大量的if.else语句转移成了一个个独立的类。 
	 
	*/  
	  
	package cn.itheima;  
	  
	public abstract class WeekDay {  
	    private WeekDay(){}  
	  
	    public final static WeekDay SUN=new WeekDay(){  
	        public WeekDay nextDay(){  
	            return MON;  
	        }  
	    };  	      
	    public final static WeekDay MON=new WeekDay(){  
	        public WeekDay nextDay(){  
	            return SUN;  
	        }  
	    };  
	      
	    public abstract WeekDay nextDay();  
	  
	    public String toString(){  
	        return this==SUN?"SUM":"MON";  
	    }  
	}  

四.枚举的应用

1.     枚举中静态方法

A.      valueOf(Stringe);

将给定的字符串转为该枚举中的对应元素或对象。

B.      values();

返回一个包含枚举类中的所有枚举元素的数组。

2.     非静态的方法

A.      StringtoString();返回枚举的名称

B.      intordinal();返回枚举值在枚举类中的顺序,按照定义的顺序排。

C.      ClassgetClass();获取对应的类名

D.     Stringname();返回此枚举常量的名称,在其枚举声明中对其进行声明。

练习代码2:

 public class WeekdayTest
{
	public static void main(String[] args)
	{
		Weekday[] days = Weekday.values();
		         for(Weekday day : days)
		         {
		               System.out.println("今天是: "+day);
		               System.out.println("明天是:"+day.nextDay());
		               System.out.println("===================");
		         }
	}
	//定义一个内部枚举类
	enum Weekday
	{
//每个元素使用匿名内部类的方法来实现抽象方法,返回当天的下一天是星期几
		       MON
		       { 
			    	   @Override 
			    	public Weekday nextDay()
			    	{
			    		  return TUE;
			    	}
		       } ,
		       TUE
		       {
			    	   @Override
			    	public Weekday nextDay()
			    	{
	
			    		return WED;
			    	}
		       }, 
		       WED
		       {
			    	   @Override
			    	public Weekday nextDay()
			    	{
			    		return THU;
			    	}
		       },
		    	THU
		       {
		    		  @Override
		    		public Weekday nextDay()
		    		{
		    			return FRI;
		    		}
		       },
		       FRI
		       {
		    	 @Override
		    	public Weekday nextDay()
		    	{
		    		return SAT;
		    	}   
		       },
		       SAT
		       {
		    	    @Override
		    	    public Weekday nextDay()
		    	    {
		    	    	return SUN;
		    	    }
		       },
		       SUN
		       {
		    	    @Override
		    	    public Weekday nextDay()
		    	    {
		    	    	return MON;
		    	    }
		       };
		       //定义一个抽象方法来表示下一天是星期几
		       public abstract Weekday nextDay();
	}
}

练习代码3:


	package cn.itheima;  
	  
	public class EnumDemo {  
	    public static void main(String[] args) {  
	        WeekDay weekDay=WeekDay.MON;  
	        System.out.println(weekDay);//输出枚举常量名  
	        System.out.println(weekDay.name());//输出对象名  
	        System.out.println(weekDay.getClass());//输出对应类  
	        System.out.println(weekDay.toString());//输出枚举对象名  
	        System.out.println(weekDay.ordinal());//输出此对象在枚举常量的次序  
	        System.out.println(WeekDay.valueOf("WED"));//将字符串转化为枚举常量  
	        System.out.println(WeekDay.values().length);//获取所以的枚举元素,并打印其长度  
	    }  
	    //定义枚举内部类  
	    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");  
	        }  
	    }  
	}  

练习代码4:

public class EnumTest {  
	    public enum TrafficLamp{  
	        RED(30){  
	            public TrafficLamp nextLamp(){  
	                return GREEN;  
	            }  
	        },  
	        GREEN(30){  
	            public TrafficLamp nextLamp(){  
                return YELLOW;  
	            }  
        },  
        YELLOW(5){  
	            public TrafficLamp nextLamp(){  
	                return RED;  
	            }  
	        };  
	        private int time;  
	        //构造器  
	        private TrafficLamp(int time){  
	            this.time=time;}  
	        //抽象方法  
	        public abstract TrafficLamp nextLamp();  
	    }       
	    public static void main(String[] args)
		{
	    	TrafficLamp[] tls = TrafficLamp.values();
	    	for(TrafficLamp tl : tls )
	    	{
	    		   System.out.println( "当前亮起的灯是:" +tl);
	    		   System.out.println( "当前灯亮起的时长是:" +tl.time);
	    		 System.out.println( "下一个亮起的等是:" +tl.nextLamp());
	    	}
		}





 

你可能感兴趣的:(java,枚举)