---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
枚举 ,JKD5.0引入的重磅新新特性。
枚举用起来非常方便,也非常实用:
public enum Operations {
PLUS,MINUS,TIMES,DEVIDE;
public double apply(double x, double y){
switch(this){
case PLUS : return x + y;
case MINUS : return x - y;
case TIMES : return x * y;
case DEVIDE : return x / y;
}
throw new RuntimeException("不支持" + this + "这种操作符");
}
}
上面的枚举定义了几种基本算法,用起来非常方便:
Operations[] opers = Operations.values();
for(Operations op : opers){
double result = op.apply(20, 20);
System.out.println(op + "< -- > " + result);
}
然而枚举的功能远远不止于此,下面的枚举虽然没有Switch语句那么简洁,但是非常安全也非常灵活:
public enum PayDay {
MONDAY(PayType.WEEKDAY), TUESDAY(PayType.WEEKDAY), WEDNESDAY(PayType.WEEKDAY),
THURSDAY(PayType.WEEKDAY), FRIDAY(PayType.WEEKDAY),
SATURDAY(PayType.WEEKEND), SUNDAY(PayType.WEEKEND);
private PayType payType;
PayDay(PayType payType) {
this.payType = payType;
}
public double pay(double hours, double rate) {
return this.payType.pay(hours, rate);
}
private enum PayType {
WEEKDAY {
public double overtimePay(double hours, double rate) {
return hours <= HOURS_PERDAY ? 0 : (hours - HOURS_PERDAY)
* rate;
}
},
WEEKEND {
public double overtimePay(double hours, double rate) {
return hours * rate * 2;
}
};
public double pay(double hours, double rate) { // 计算当天工资
double baseSalary = hours * rate;
return baseSalary + this.overtimePay(hours, rate);
}
public abstract double overtimePay(double hours, double rate); // 计算加班工资
private static final int HOURS_PERDAY = 8; // 每天工作时间
}
}
上面的枚举可以用来计算当天工资,而且可以分为工作日和非工作日还可以计算加班工资。
我的测试代码如下:
PayDay[] days = PayDay.values();
for(PayDay payDay : days){
System.out.println(payDay + " <---> " + payDay.pay(10, 50));
}
枚举不仅仅只有这些,枚举还可以利用接口来扩展:
先定义一个接口 OperationInter:
public interface OperationInter {
public double apply(double x, double y);
}
下面的枚举是实现了OperationInter接口的枚举:
public enum Operation implements OperationInter {
PLUS("+") {
public double apply(double x, double y) {
return x + y;
}
},
MINUS("-") {
public double apply(double x, double y) {
return x - y;
}
},
TIMES("*") {
public double apply(double x, double y) {
return x * y;
}
},
DIVIDE("/") {
public double apply(double x, double y) {
return x / y;
}
};
Operation(String symbol) {
this.symbol = symbol;
}
@Override
public String toString() {
return this.symbol;
}
private String symbol;
}
在定义一个实现了Operation接口的枚举:
public enum ExtendOperation implements OperationInter{
EXP("^"){
public double apply(double x, double y){
return Math.pow(x, y);
}
},REMAINDER("%"){
public double apply(double x, double y){
return x % y;
}
};
ExtendOperation(String symbol){
this.symbol = symbol;
}
@Override
public String toString(){
return this.symbol;
}
private String symbol;
}
下面就来试试实现接口对枚举的扩展有什么影响:
public static <T extends Enum<T> & OperationInter> void print(Class<T> opSet,double x,double y){
for(OperationInter inter : opSet.getEnumConstants()){
double result = inter.apply(x, y);
System.out.println(inter + " < -- > " + result);
}
}
<T extends Enum<T> & OperationInter> 这个复杂的泛型不仅保证Class既是枚举类型而且也是OperationInter的子类
print(Operation.class,50,20);
print(ExtendOperation.class,50,20);
枚举的功能远远不止于此,我就只列出了这么多了,其他的功能还要继续去试试。
使用枚举也需要注意:
每个枚举都有 oridinal方法,该方法返回每个枚举再类型中的的数字位置,列如:
public enum EnumOridinal {
FIRST,SECOND,THIRD,FOURTH;
public int position(){
return this.ordinal() + 1;
}
}
大家千万别这么做,因为这个方法确实可以返回该枚举所在数字位置,但是当往这个枚举或者添加新的枚举再或枚举顺序打乱了,那么position方法返回的值又不同, 总的来说,千万别用oridinal方法返回枚举在类型中的数字位置,这么做那么你的后期维护简直就是一场噩梦!