为什么要有枚举?
问题:要定义星期几或性别的变量,该怎么定义?假设用1-7分别表示星期一到星期日,但有人可能会写成int weekday = 0;或即使使用常量方式也无法阻止意外。
枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。
以前没有枚举类的时候,我们用普通类如何实现枚举功能?
定义一个TrafficLamp的类来模拟枚举功能。
私有的构造方法
每个元素分别用一个公有的静态成员变量表示
可以有若干公有方法或抽象方法。采用抽象方法定义nextDay就将大量的if.else语句转移成了一个个独立的类。
1 private abstract class TrafficLamp { 2 private TrafficLamp(int time){this.time = time;}//私有化构造函数 3 4 private int time; 5 //采用抽象方法定义nextLamp就将大量的if.else语句转移成了一个个独立的类。 6 public abstract TrafficLamp nextLamp(); 7 //每个元素分别用一个公有的静态成员变量表示 8 public final static TrafficLamp RED= new TrafficLamp(30){ 9 10 public TrafficLamp nextLamp() { 11 12 return GREEN; 13 } 14 15 }; 16 public final static TrafficLamp GREEN = new TrafficLamp(45){ 17 18 public TrafficLamp nextLamp() { 19 20 return YELLOW; 21 } 22 23 }; 24 public final static TrafficLamp YELLOW = new TrafficLamp(10){ 25 26 public TrafficLamp nextLamp() { 27 28 return RED; 29 } 30 31 }; 32 public String toString(){ 33 if(this == RED){ 34 return "RED"; 35 }else if(this == GREEN){ 36 return "GREEN"; 37 }else 38 return "YELLOW"; 39 } 40 }
枚举的应用
枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。
枚举元素必须位于枚举体中的最开始部分,枚举元素列表的后要有分号与其他成员分隔。把枚举中的成员方法或变量等放在枚举元素的前面,编译器报告错误。
带构造方法的枚举
构造方法必须定义成私有的
枚举元素RED和RED()的效果一样,都是调用默认的构造方法。
带方法的枚举
实现普通的nextLamp方法
实现抽象的nextLamp方法:每个元素分别是由枚举类的子类来生成的实例对象,这些子类采用类似内部类的方式进行定义。
枚举只有一个成员时,就可以作为一种单例的实现方式。
1 import java.util.Date; 2 public class EnumTest { 3 4 public static void main(String[] args) { 5 TrafficLamp tl = TrafficLamp.RED; 6 //ordinal()返回枚举值在枚举中的索引位置,从0开始 7 System.out.println(tl.toString()); 8 System.out.println(tl.ordinal()); 9 System.out.println(tl.equals(TrafficLamp.RED)); 10 11 //可以使用高级for循环遍历枚举中的值 12 System.out.println("遍历枚举TrafficLamp中的值"); 13 for(TrafficLamp tr: TrafficLamp.values()){ 14 System.out.println(tr); 15 } 16 System.out.println("枚举TrafficLamp中的值有:"+TrafficLamp.values().length+"个"); 17 18 /*枚举默认实现了java.lang.Comparable接口. 19 比较此枚举与指定对象的顺序。在该对象小于、等于或大于指定对象时,分别返回负整数、零或正整数。 20 枚举常量只能与相同枚举类型的其他枚举常量进行比较。该方法实现的自然顺序就是声明常量的顺序。*/ 21 System.out.println(TrafficLamp.RED.compareTo(TrafficLamp.GREEN)); 22 23 //枚举可以在switch中使用 24 TrafficLamp color=TrafficLamp.RED; 25 switch(color){ 26 case RED:System.out.println("it's red");break; 27 case GREEN: System.out.println("it's green");break; 28 case YELLOW: System.out.println("it's yellow");break; 29 } 30 } 31 //定义一个枚举类 32 public enum TrafficLamp{ 33 RED(30){ 34 public TrafficLamp nextLamp(){ 35 return GREEN; 36 } 37 }, 38 GREEN(45){ 39 public TrafficLamp nextLamp(){ 40 return YELLOW; 41 } 42 }, 43 YELLOW(5){ 44 public TrafficLamp nextLamp(){ 45 return RED; 46 } 47 }; 48 public abstract TrafficLamp nextLamp(); 49 private int time; 50 private TrafficLamp(int time){this.time = time;} 51 } 52 } 53 ---------- java ---------- 54 RED 55 0 56 true 57 遍历枚举TrafficLamp中的值 58 RED 59 GREEN 60 YELLOW 61 枚举TrafficLamp中的值有:3个 62 -1 63 it's red 64 65 输出完成 (耗时 0 秒) - 正常终止