枚举(enum):
枚举是一种特殊的类,其中的每个元素都是该类的一个实例对象,例如可以调WeekDay.SUN.getClass().getName等。让某个类型的变量的取值只能为若干个因定值中的一个,枚举可以让编译器在编写代码时期就能判断其代码正确与否。
为什么要有枚举?
像有一些须要固定值来描述,且不让更改。如:定义的星期几或性别等。假用1-7 分别来表示星期一到星期日,但如果有人写成了 int weekday = 0; 以为是星期一那怎么办?所以须要枚举来限制weekday 只能取对应的几个固定值。
使用enum枚举类的特点:
1,类默认继承了 java.lang.Enum 类
2,参数列表必须放在第一行。
3,参数列表是其类的子类。
4,底层已完成了对toString()方法的复写。
5,参数列表底层已完成了初始化。
6,属性的修饰关键字无须书写,底层已完成。
7,构造方法必须定义成私有的。
8,和普通 Java 类一样枚举类可以实现一个或多个接口。
9,若需要每个枚举值在调用实现的接口方法呈现出不同的行为方式, 则可以让每个枚举值分别来实现该方法。
10,枚举类对象的属性不应允许被改动。
11,JDK 1.5 中可以在 switch 表达式中使用枚举类的对象作为表达式, case 子句可以直接使用枚举值的名字, 无需添加
枚举类作为限定。
12,如果枚举里只有一个成员时,同单例设计模式一样,可以作为一个单例来使用。
用枚举来写单例的好处:构造方法不用写
举例说明:下例一
用普通类如何实现枚举功能?
1,私有的构造方法
2,每个元素分别用一个公有的静态成员变量表示
3,可以有若干个公有方法或抽象方法,例如,要提供nextDay方法必须是抽象的。
举例说明:下例二
带有构造方法的枚举类:
在枚举中也可以定义构造方法,方法等。
如果定义了有参数构造方法,那么还可以通过其参数列表传值。
心得:如果我们须要固定某些调用值,就可以使用枚举,如:性别只让其调用男、女. 星期只让其调用周一至同日等。 把参数定义为一个可以当单例设计模式来使用。枚举类就是由内部类来完成。其参数列表就是其子类。如果想 让其参数列表(属性)完成不同的操作,可以使用抽象的方法。还可以避免大量的if...else语句。
例一:
package enumtext2;
public class enumtext2 {
public static void main(String[] args) {
System.out.println("调用"+WeekDay.MON);
//设定为枚举的某个值
System.out.println(WeekDay.valueOf("TUE"));
//获取枚举对象字节码
Class sum = WeekDay.SUM.getDeclaringClass();
//把枚举转换成数组
WeekDay [] arrayweekday = WeekDay.values();
System.out.println(arrayweekday.length);
//红绿灯的切换
System.out.println(TrafficLamp.RED+"--红灯停");
System.out.println(TrafficLamp.RED.nextLamp()+"--绿灯走。。。");
System.out.println(TrafficLamp.RED.nextLamp().nextLamp()+"--黄灯注 意!!!");
}
/*
* 枚举类自动调用java.lang.Enum包
*
* 要求:实现一周7天的模拟,其调用范围只能是其参数列表中的一个固定值
* */
public enum WeekDay
{
/*
* 注意:
* 1,这里参数列表结束分号可有可无,但是如果后面还有语句的话,就必须要加上
* 2,这个参数列表表必须放在第一行。
* 3,参数后加(参数)如:SUM(3),表示的是调用有参构造器
* 4,这些参数列表都是WeekDay的子类
* 5,参数列表底层已完成了初始化
* 6,如果枚举里只有一个成员时,同单例设计模式一样,可以作为一个单例来使用
* 7,属性的修饰关键字无须书写,底层已完成。
* */
SUM(3),MON(5),TUE,WED,THI,FRI,SAT;
private WeekDay() { System.out.println("初始化...first");}
private WeekDay(int day) {System.out.println("初始化......second");}
//枚举类底层已完成了对toString()方法的复写
}
/*
* 要求:实现交通灯的切换
* 用抽象的方法来完成
**/
public enum TrafficLamp{
//参数列表底层已完成了初始化,只须复写父类的抽象方法即可
RED(30){ //停留30秒
@Override
public TrafficLamp nextLamp() { //完成抽象方法的复写
return GREEN;
}
},
GREEN(45){
@Override
public TrafficLamp nextLamp() {
return YELLOW;
}
},
YELLOW(5){
@Override
public TrafficLamp nextLamp() {
return RED;
}
};
/*
* 用抽象方法来实现nextLamp()方法,可以避免大量的if...else语句
* 让其子类自己去完成相应的操作
* */
public abstract TrafficLamp nextLamp();
private int time;
TrafficLamp(){}
TrafficLamp(int time)
{
this.time = time;
}
}
}
例二:
用普通类来实现枚举功能
class EnumDemo
{
public static void main(String[] args)
{
//方法一
Season s = Season.SPRING;
System.out.println(s);
System.out.println(s.nextSeason());//下一个季节
//方法二
Season2 s2 = Season2.SPRING;
System.out.println(s2);
System.out.println(s2.nextSeason());//下一个季节
}
}
/*
用普通类来实现枚举功能
步骤:
1,私有的构造方法
2,每个元素分别用一个公有的静态成员变量表示
3,可以有若干个公有方法或抽象方法。
要求:
模拟 春夏秋冬四个季节切换
方法一:用抽象方法,让其子类去实现切换
*/
public abstract class Season
{
private Season(){} //私有化构造器
public final static Season SPRING = new Season(){
public Season nextSeason() //实现其父类抽象方法
{
return SUMMER;
}
};
public final static Season SUMMER = new Season(){
public Season nextSeason()
{
return AUTUMN;
}
};
public final static Season AUTUMN = new Season(){
public Season nextSeason()
{
return WINTER;
}
};
public final static Season WINTER = new Season(){
public Season nextSeason()
{
return SPRING;
}
};
public abstract Season nextSeason();
public String toString() //复写toString
{
if(this==SPRING)
return "SPRING";
else if(this==SUMMER)
return "SUMMER";
else if(this==AUTUMN)
return "AUTUMN";
else
return "WINTER";
}
}
//上面的类也可以改写成:如 Season2 枚举类
//方法二
public class Season2
{
private Season2(){}
public final static Season2 SPRING = new Season2();
public final static Season2 SUMMER = new Season2();
public final static Season2 AUTUMN = new Season2();
public final static Season2 WINTER = new Season2();
public Season2 nextSeason()
{
if(this==SPRING)
return SUMMER;
else if(this==SUMMER)
return AUTUMN;
else if(this==AUTUMN)
return WINTER;
else
return SPRING;
}
public String toString()
{
if(this==SPRING)
return "SPRING";
else if(this==SUMMER)
return "SUMMER";
else if(this==AUTUMN)
return "AUTUMN";
else
return "WINTER";
}
}