zoukankan      html  css  js  c++  java
  • Java之花样玩枚举

    一,枚举的引出

    设定一个场景,业务需要我们的一个进件有若干状态,怎么表示这些状态呢?大部分可能会直接用static final 表示一个int类型的变量。如下:

        //订单状态
        public static final int ORDER_DEPOT_UNPAY = 0;
        public static final int ORDER_DEPOT_PAID = 1;
        public static final int ORDER_DEPOT_TIMOUT = 2;

    然后接下来的业务逻辑就是用这些常量值来带指各种基本业务含义。但是这样的弊端也有如下

    1. 它只是一个int类型的数据而已,如果我们定义了别的变量然后数字跟他一样怎么办?比如

        public static final int ORDER_LOGISTICS_READY = 0;
        public static final int ORDER_LOGISTICS_TRANSPORT = 1;
        public static final int ORDER_LOGISTICS_ARRIVED = 2;

    我想用上面三个状态的一个类型,而错误的输入称了下面的一个类型怎么办?,因为在业务实现上他们最终展示的都是一个数字,还TM一样!。

    2. 这些变量我们只是一个编号,获得编号后如果我想知道具体含义怎么办?你还要构造一个编号跟含义的映射表。

    3. 这些常量是static final类型的啊,在类加载的时候,如果有些地方使用了这样常量,在类加载的间接引用会直接编程常量引用的!

    这个时候用枚举更好一些。

        public enum Depot {UNPAY, PAID, TIMOUT}//0,1,2
        public enum Logistics {READY, TRANSPORT, ARRIVED}// 0,1,2

    然后调用的时候如果需要值可以直接这样调用(枚举类会自动给实例编号默认从0开始)

        public static void main(String[] args) {
    
            System.out.println(Depot.UNPAY);
            System.out.println(Depot.UNPAY.ordinal());
    
        }

    二,枚举进阶

    但是如果这时候我们将他们的具体序号变换了咋吧?比如

        //订单状态
        public static final int ORDER_DEPOT_UNPAY = 0;
        public static final int ORDER_DEPOT_PAID = 3; //值变化了 
        public static final int ORDER_DEPOT_TIMOUT = 2;

    我们可以对枚举类进行丰富化操作,使用的前提是要知道枚举类里类型一定是这个类的若干实例。其余的操作跟类和对象操作没有任何区别!。demo如下

    public enum DepotEnum {
        UNPAY(0, "未支付"), PAID(1, "已支付"), TIMOUT(-1, "超时");
    
        private int status; //状态
        private String desc; // 含义描述
        private String dbInfo;//其他属性
    
        private DepotEnum(int status, String desc) {
            this.status = status;
            this.desc = desc;
        }
    
        public int getStatus() {
            return status;
        }
    
        public String getDesc() {
            return desc;
        }
    
        public String getDbInfo() {
            return dbInfo;
        }
    
        public int calcStatus(int params) {
            return status + params;
        }
    
        public static void main(String[] args) {
            for (DepotEnum e : DepotEnum.values()) {
                System.out.println(e + ":" + e.calcStatus(14));
            }
        }
        
    }
    

    三,再进阶

    在枚举中如果我们的若干状态要跟一些行绑定在一起怎么办? JDM提供了枚举类型也可用在switch中,比如我们的加减乘除。我们可以在里面实现这样的switch 功能。

    public class ActiveEnum {
    	
    	public enum NormalActive{
    		PLUS,MINUS,MULTI,DIVIDS;
    		
    		double oper(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(); // 这个存在的含义仅仅是替换 default
    		}		
    	}
    
    	public static void main(String[] args) {
    		System.out.println(NormalActive.PLUS.oper(0.1, 0.2));
    	}
    }

    那可能有的时候我们需要新添加功能了比如新添加一个微分(DIFFER)功能 咋办,我是不是要添加枚举类型,添加switch语句。

    这个时候我们可以再对代码进行优化(时刻谨记枚举类型是类对实例)。

    public class ActiveEnum {
    
    	public enum BetterActive{
    		PLUS {
    			@Override
    			double oper(double x, double y) {
    				return x+y;
    			}
    		},MINUS {
    			@Override
    			double oper(double x, double y) {
    				return x-y;
    			}
    		};
    		
    		abstract double oper(double x,double y); // 抽象类的引入
    		 
    	}
    	public static void main(String[] args) {
    		System.out.println(NormalActive.PLUS.oper(0.1, 0.2));
    	}
    	
    }
    

    四,策略枚举引入

    比如我们现在要算员工加班费,规则算工作日加班2倍工资,节假日加班3倍工资。

    /**
     *@author sowhat
     *类说明:加班费计算,工作日加班2倍,节假日3倍
     */
    enum PayDay {
    	MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
    	
    	private static final int HOURS_WORK = 2;
    	private static final int HOURS_REST = 3;
    	
    	//超时时间
    	double pay(double hoursOvertime) {
    		switch(this) {
    		case SATURDAY:case SUNDAY:
    			return hoursOvertime*HOURS_REST;
    		default:
    			return hoursOvertime*HOURS_WORK;
    		}
    	}
    }

    但是这个时候我如果要添加一个51节日的呢? 我们可以考虑引入策略枚举。然后用外部枚举来包装策略枚举。

    public enum BetterPayDay {
    	MONDAY(PayType.WORK), TUESDAY(PayType.WORK), WEDNESDAY(
    			PayType.WORK), THURSDAY(PayType.WORK), FRIDAY(PayType.WORK), 
    	SATURDAY(PayType.REST), SUNDAY(PayType.REST),WUYI(PayType.REST);
    
    	private final PayType payType; // 成员变量 然后定义一个外部枚举来包装 策略枚举。
    
    	BetterPayDay(PayType payType) {
    		this.payType = payType;
    	}
    
    	double pay(double hoursOvertime) {
    		return payType.pay(hoursOvertime);
    	}
    
    	//策略枚举 我们只定义 工作日还是节假日的薪资计算方法。
    	private enum PayType {
    		WORK {
    			double pay(double hoursOvertime) {
    				return hoursOvertime*HOURS_WORK;
    			}
    		},
    		REST {
    			double pay(double hoursOvertime) {
    				return hoursOvertime*HOURS_REST;
    			}
    		};
    		private static final int HOURS_WORK = 2;
    		private static final int HOURS_REST = 3;
    
    		abstract double pay(double hoursOvertime);//抽象计算加班费的方法
    	}
    	
    	public static void main(String[] args) {
    
    		System.out.println(BetterPayDay.MONDAY.pay(7.5));
    	}
    }
    
    关注公众号 海量干货等你
  • 相关阅读:
    配置错误定义了重复的“system.web.extensions/scripting/scriptResourceHandler” 解决办法
    js 获取cookie
    jQuery+Ajax+PHP 制作简单的异步数据传输(测试用户名是否可用)
    既之前的基础,先写个简单的PHP 与数据库 的数据交流
    Web 后端--PHP 与数据库的交互
    MySQL 忘记密码怎么办?
    MySQL 继续-- Win7 安装及后续工作
    数据库初识--从MySQL 出发
    在PHP中使用MySQL Mysqli操作数据库 ,以及类操作方法
    电脑使用--快捷键等
  • 原文地址:https://www.cnblogs.com/sowhat1412/p/12734215.html
Copyright © 2011-2022 走看看