在做项目的过程中,经常会遇到订单的不同状态,比如定义为:
//未支付
public static final int ORDER_DEPOT_UNPAY = 0;
//已支付
public static final int ORDER_DEPOT_PAYED = 1;
//支付超时
public static final int ORDER_DEPOT_TIMOUT = 2;
这样写的缺点:1.变量值相似,容易搞混 2.由于增加新项,导致引用地方跟着修改,但是静态常量在编译时就直接被替换为变量的真实值,必然导致所有用到这里静态常量的类要重新的编译
这个时候一般为了好管理,避免上面的问题,大家都会采用枚举:
public enum PayStatus{UNPAY,PAYED,TIMOUT}
这个时候,如果想要也给UNPAY赋值为0,PAYED赋值为1,TIMEOUT赋值为2,该怎么做
这里需要注意的就是,其实枚举里面也可以定义成员变量,成员方法,构造方法,每个枚举选项,其实就是这个枚举的对象实例!
这句话如何理解,下面的例子,可以更好的表述:
public enum PayStatusEnum {
//枚举的选项,相当于该枚举类型的对象实例
//UNPAY 代表 PayStatusEnum的对象名称
// 0 代表 对象UNPAY的属性status的值
// “未支付” 代表 对象UNPAY的属性desc的值
UNPAY(0,"未支付"),
PAYED(1,"已支付"),
TIMEOUT(2,"支付超时");
private int status;
private String desc;
private PayStatusEnum(){
}
private PayStatusEnum(int status, String desc) {
this.status = status;
this.desc = desc;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public static void main(String[] args) {
System.out.println(PayStatusEnum.PAYED.status);//运行结果:0
}
}
看到这里,是不是已经完全颠覆了你对enum的认知?其实enum的使用远不止这些,比如下面的例子:
public class EnumDemo {
public enum MATH{
PLUS,MINUS,MULTI,DIVIDS;
double mathOper(double no1,double no2){
switch(this){
case PLUS:return no1+no2;
case MINUS:return no1-no2;
case MULTI:return no1*no2;
case DIVIDS:return no1/no2;
}
throw new UnsupportedOperationException();
}
}
public static void main(String[] args) {
double result = MATH.PLUS.mathOper(1, 2);
System.out.println(result);//3.0
}
}
以上代码,在枚举中定义了成员方法,并且在main函数中调用了,但是这个时候如果需要增加一个DIFFER选项,直接在代码中添加:
public enum MATH{
PLUS,MINUS,MULTI,DIVIDS,DIFFER;
double mathOper(double x,double y) {
switch(this) {
case PLUS:return x+y;
case MINUS:return x-y;
case MULTI:return x*y;
case DIVIDS:return x/y;
}
throw new UnsupportedOperationException();
}
}
以上代码并没有编译出错,但是当我调用MATH.DIFFER.mathOper(1,2);就会抛出下面抛出的异常,我们的代码怎么才能做到,错误或者异常在编译的时候就发现,而不是在运行时发现呢?答案,当然是肯定的。
public enum MATHBETTER{
PLUS {
@Override
double mathOper(double no1, double no2) {
return no1+no2;
}
},MINUS {
@Override
double mathOper(double no1, double no2) {
return no1-no2;
}
},MULTI {
@Override
double mathOper(double no1, double no2) {
return no1*no2;
}
},DIVIDS {
@Override
double mathOper(double no1, double no2) {
return no1/no2;
}
},DIFFER;//此行如果不重写mathOper方法,就会编译报错
//声明了抽象方法,如果想要实例化话出对象,必须实现此方法
abstract double mathOper(double no1,double no2);
}
呵呵 讲了这么多,现在练习一下吧:公司计算加班工资,周一到周五,加班工资是平时薪资的2倍,周六和周日是平时薪资的3倍
public enum HoursCount{
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
private final static int WORKTIME = 2;
private final static int RESTTIME = 3;
double hoursCount(int hours){
switch(this){
case SATURDAY:
case SUNDAY: return hours*RESTTIME;
default:return hours*WORKTIME;
}
}
}
上面代码还是存在一个问题,如果枚举选项增加春节,五一,十一这些节假日,就会修改到响应的计算方法的代码,这和编码的基本原则相违背,下面我们就通过策略模式,修改以上代码:
public enum HoursCountBetter{
MONDAY(PayType.WORK), TUESDAY(PayType.WORK), WEDNESDAY(PayType.WORK),
THURSDAY(PayType.WORK), FRIDAY(PayType.WORK), SATURDAY(PayType.REST),
SUNDAY(PayType.REST),WUYI(PayType.REST);
final PayType payType;
HoursCountBetter(PayType payType){
this.payType = payType;
}
double hoursCount(double hours){
return payType.hoursCount(hours);
}
//策略模型
private enum PayType {
WORK {
double hoursCount(double hoursOvertime) {
return hoursOvertime*HOURS_WORK;
}
},
REST {
double hoursCount(double hoursOvertime) {
return hoursOvertime*HOURS_REST;
}
};
private static final int HOURS_WORK = 2;
private static final int HOURS_REST = 3;
abstract double hoursCount(double hoursOvertime);
}
}