为什么要用枚举?
比如要定义星期几,有的人用1-7,而有的用0-6,这就很容易导致问题的出现
枚举就是要让某个类型的变量的取值只能为若干个值中的一个,否则,编译器报错,枚举可以让编译器在编译时期就可以检测出源程序填写的非法值,而用普通变量模拟枚举的方法无法实现这一目标
用普通类来模拟实现枚举功能:
1.将构造方法私有
2.每个元素分别有一个公用的静态成员变量
3.可以有若干个公有方法或抽象方法,而采用抽象方法定义的nextDay就将大量的if..else变换成一个一个独立的类
class WeekDay {
private WeekDay(){}
public final static WeekDay SUN = new WeekDay();
public final static WeekDay MON = new WeekDay();
public WeekDay nextDay(){
return (this==SUN)?MON:SUN;
}
public String toString(){
return (this==MON)?"MON":"SUN";
}
}
public class EnumDemo {
public static void main(String[] args) {
System.out.println(WeekDay.SUN.nextDay());
}
}
也可以是将方法定义为抽象的,每个固定的WeekDay对象的子类去复写的
在一个类中编写完各个枚举类和测试调用类,那么就可以将枚举类定义成调用类的内部类
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(){//匿名内部类,子类来写nextDay方法
public WeekDay nextDay() {
return SUN;
};
};
public abstract WeekDay nextDay();
public String toString(){
return (this==MON)?"MON":"SUN";
}
}
顺便复习一下:
class Demo{}
new Demo(){} ->new 一个Demo的子类,{}中是子类的代码,这个表示,子类调用的是父类的无参的构造方法
new Demo(20){} ->new子类的实例对象,调用父类的有参的构造方法
枚举的基本应用:
定义一个Week的枚举
枚举是一种特殊的类,其中的每个元素都是该类的一个实例对象,例如可以用WeekDay.SUN.getClass().getName();
public class EnumDemo {
public static void main(String[] args) {
System.out.println(WeekDay.SUN.nextDay());
Week w = Week.SUN;
System.out.println(w);
System.out.println(w.name());
System.out.println(w.ordinal());//排第几
System.out.println(w.getClass());
System.out.println(Week.valueOf("SUN"));//将字符串变换成对应的枚举元素
System.out.println(Week.values().length);//将枚举中的每一个元素,都装进数组
}
public enum Week{//定义一个枚举类
SUN,MON;
}
}
实现带有构造方法的枚举
public enum Week{//定义一个枚举类
SUN,MON;//所有的东西都必须放在枚举值列表下面
private Week(){System.out.println("WU");};//枚举类的构造方法必须是private
private Week(int i){System.out.println("I");};
}
按照上面main执行,执行的都是无参的Week构造函数,因为只要用到Week枚举类,它里面的静态成员变量都会被初始化
如果非要用有参的那个构造函数那么,枚举值就必须指定参数
public enum Week{
SUN(5),MON();
private Week(){System.out.println("WU");};
private Week(int i){System.out.println("I");};
}
带有抽象方法的枚举:
public class EnumDemo {
public static void main(String[] args) {
System.out.println(Month.March.nextMonth());
}
public enum Month{
//January,February,March,April;
January(31){
public Month nextMonth() { return February;}
},February(28) {
public Month nextMonth() {return March; }
},March(30) {
public Month nextMonth() {return April; }
},April(31) {
public Month nextMonth() { return January; }
};
public abstract Month nextMonth();//抽象方法,返回类型是自己类型
private int time ;
private Month(int time){ this.time = time ;}
public String toString(){
if(this==January)return "January";
else if(this==February) return "February";
else if(this==March) return "March";
else return "April";
}
}
} 当枚举只有一个成员时,就可以作为一种单例的实现方式。