1.作用
为什么要有枚举?
问题: 要定义星期几或性别的变量,该怎么定义?假设用1-7分别表示星期一到星期日,但有人可能会写成int weekday = 0;或即使使用常量方式也无法阻止意外.
枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错!
枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标.
2.普通类模拟其原理
SUN和MON的示例:元素相当于实现了遍历类的抽象方法的子类;
public class EnumTest {
public static void main(String[] args) {
WeekDay1 weekDay=WeekDay1.MON;
System.out.println(weekDay.nextDay());
}
}
public abstract class WeekDay1 {
private WeekDay1(){}
// 元素定义为有关键字的内部类
public final static WeekDay1 SUN=new WeekDay1(){
public WeekDay1 nextDay(){
return MON;
}
};
public final static WeekDay1 MON=new WeekDay1(){
public WeekDay1 nextDay(){
return SUN;
}
};
public abstract WeekDay1 nextDay();
/* public final static WeekDay SUN=new WeekDay();
public final static WeekDay MON=new WeekDay();
public WeekDay nextDay(){
if(this == SUN){
return MON;
}else{
return SUN;
}
}*/
public String toString(){
return this == SUN?"SUN":"MON";
}
}
模拟可知:
(1)内部元素都是静态常量!
(2)枚举也是抽象类,可以建立抽象方法返回本身类型;
(3)每一个静态常量元素都可以实现抽象方法,成为一个实例对象!
知识扩展:通过抽象方法nextDay()重载,每一个枚举元素都实现为一个类,简化了if-else的书写;
3. jdk1.5枚举的建立
关键字 enum
枚举就是要让某个类型的变量的取值只能为若干固定值之中的一个,其中的每一个元素都是该类的一个对象!相当于内部类.
定义枚举类的关键字enum,
示例:
public enum WeekDay{
SUN,MON,TUE,WED,THI,FRI,SAT
}
4.enum的方法和元素调用enum类的构造方法
四大重点方法:
枚举元素.name()
枚举元素.ordinal()
enum类.valueOf("args")
enum类.values("args")
示例:
public class EnumTest {
public static void main(String[] args) {
//取出enum类中的元素;
WeekDay weekDay2=WeekDay.FRI;
System.out.println(weekDay2);//自动toString();
//得到元素名称;
System.out.println(weekDay2.name());
//得到具体元素的下标位[];
System.out.println(weekDay2.ordinal());
//通过字符串返回获得对应enum元素;
System.out.println(WeekDay.valueOf("SUN").toString());
//不能直接遍历enum,但可转换成数组,方法.values()
System.out.println(WeekDay.values().length);//遍历元素数组的长度
}
// 定义枚举类的关键字enum,定义后内部元素静态加载完毕;
public enum WeekDay{
SUN(1),MON(),TUE,WED,THI,FRI,SAT;//可以给元素加构造方法,给元素类加构造方法后,必须有;号.
//加载enum后,会静态遍历一次,每个静态常量都会依次调用父类的构造方法;
//当有多个构造方法时,还可以构建对应的参数(如这里SUN(1))方式选择每个元素具体调用哪个构造方法.
private WeekDay(){System.out.println("first");}
private WeekDay(int day){System.out.println("second");}
}
}
5.实现带有抽象方法的枚举
红绿灯的实现示例:
enum TrafficLamp{
RED(30){
public TrafficLamp nextLamp() {
return YELLOW;
}
},
YELLOW(40){
public TrafficLamp nextLamp() {
return GREEN;
}
},
GREEN(45){
public TrafficLamp nextLamp() {
return RED;
}
};
public abstract TrafficLamp nextLamp();//抽象类不写body
private int time;
private TrafficLamp(int tiem){this.time = time;}
}
public class EnumDemo {
public static void main(String[] args) {
System.out.println(TrafficLamp.RED.nextLamp());
System.out.println(TrafficLamp.RED.nextLamp().getTime());
}
}