package com.zghw.base.enumx; import java.text.DateFormat; import java.util.Date; /** * 允许程序员为enum实例编写方法,从而为每个enum实例赋予各自不同的行为。 * 要实现常量相关的方法,你需要为enum定义一个或多个abstract方法, * 然后为每个enum实例实现该抽象方法 * @author zghw * */ public enum ConstantSpecificMethod { DATE_TIME{ String getInfo(){ return DateFormat.getInstance().format(new Date()); } }, CLASSPATH{ String getInfo(){ return System.getenv("CLASSPATH"); } }, VERSION{ //实现抽象接口方法 String getInfo(){ return System.getProperty("java.version"); } //重写方法 void print(){ System.out.println("重写了"+this); } }; abstract String getInfo(); void print(){ System.out.println(this); } public static void main(String args[]){ for(ConstantSpecificMethod c: ConstantSpecificMethod.values()){ c.print(); System.out.println(c.getInfo()); } } /** * 在面向对象设计中,不同的行为与不同的类关联。而通过常量相关的方法, * 每个enum实例可以具备自己独特的行为,说明每个enum实例就像一个独特的类。 * 在调用getInfo()方法时,体现了多态。 */ }
package com.zghw.base.enumx; import java.util.EnumSet; /** * 洗车服务菜单实例 * * @author zghw * */ public class CarWash { public enum Cycle { UNDERBODY { void action() { System.out.println(this); } }, WHEELWASH { void action() { System.out.println(this); } }, PERWASH { void action() { System.out.println(this); } }, BASIC { void action() { System.out.println(this); } }, HOTWAX { void action() { System.out.println(this); } }, RINSE { void action() { System.out.println(this); } }, BLOWDRY { void action() { System.out.println(this); } }; abstract void action(); } EnumSet<Cycle> cs = EnumSet.of(Cycle.BASIC, Cycle.RINSE); public void add(Cycle cw) { cs.add(cw); } public void washCar() { for (Cycle c : cs) { c.action(); } } public String toString() { return cs.toString(); } public static void main(String[] args) { CarWash cc = new CarWash(); System.out.println(cc); cc.add(Cycle.BLOWDRY); System.out.println(cc); cc.add(Cycle.PERWASH); cc.add(Cycle.WHEELWASH); cc.add(Cycle.BASIC); cc.add(Cycle.BLOWDRY); System.out.println(cc); // 向EnumSet中添加的顺序并不重要,因为输出的次序决定于enum实例定义时的次序 cc.washCar(); } }
下面是自动售货机的例子,全面的使用枚举特性:
package com.zghw.base.enumx; import java.util.Random; /** * 售卖机所有输入 * * @author zghw * */ public enum Input { NICKE(15),DIME(10),QUARTER(25),DOLLAR(100), TOOTHPASTE(200),CHIPS(75),SODA(100),SOAP(50), ABORT_TRANSACTION { // 重写getValue()方法 public int getValue() { throw new RuntimeException("transaction no value"); } }, STOP { public int getValue() { throw new RuntimeException("had stop no value"); } }; // 输入对应的价格值 private int value; private Input(int value) { this.value = value; } // 枚举对应的多个构造函数 private Input() { } // 取得对应的价格 public int getValue() { return value; } static Random random = new Random(47); // 随机选择一个输入,由于STOP不是一个输入,所以随机值减少STOP public static Input randomSelect() { return values()[random.nextInt(values().length - 1)]; } }
package com.zghw.base.enumx; import static com.zghw.base.enumx.Input.*; import java.util.EnumMap; /** * 输入进行分类 * @author zghw * */ public enum Category { MONEY(NICKE,DIME,QUARTER,DOLLAR), ITEM_SELECTION(TOOTHPASTE, CHIPS,SODA,SOAP), QUIT_TRANSACTION(ABORT_TRANSACTION), SHUT_DOWN(STOP); private Input[] categories; private Category(){} private Category(Input... categories){ this.categories = categories; } //获取分类对象表 public static EnumMap<Input,Category> getCategoryMap(){ EnumMap<Input,Category> categoryMap=new EnumMap<Input,Category>(Input.class); for(Category c: Category.values()){ for(Input i:c.categories){ categoryMap.put(i, c); } } return categoryMap; } //根据输入获取分类 public static Category get(Input input){ return getCategoryMap().get(input); } }
package com.zghw.base.enumx; import static com.zghw.base.enumx.VendingMachine.StateDuration.TRANSIENT; import java.util.Arrays; import java.util.Iterator; /** * 自动售货机 责任链和状态模式 * * @author zghw * */ public class VendingMachine { // 当前自动售货机处理的状态 private static State state = State.RESTRING; // 当前输入 private static Input selection = null; // 花费钱统计 private static int amount = 0; enum StateDuration { // 持续状态 1.瞬时 TRANSIENT }; enum State { // 五种状态 1.重置2.付款3.系统配置4.取消5.终端 RESTRING { public void next(Input input) { switch (Category.get(input)) { case MONEY: amount += input.getValue(); state = ADDING_MONEY; break; case SHUT_DOWN: state = TERMINAL; break; default: break; } } }, ADDING_MONEY { public void next(Input input) { switch (Category.get(input)) { case MONEY: amount += input.getValue(); break; case ITEM_SELECTION: selection = input; if (amount < selection.getValue()) { System.out.println("不够支付" + selection); } else { state = DISPENSING; } break; case QUIT_TRANSACTION: state = GIVING_CHANGE; break; case SHUT_DOWN: state = TERMINAL; break; default: break; } } }, DISPENSING(TRANSIENT) { public void next() { System.out.println("你选择的是:" + selection); amount -= selection.getValue(); state = GIVING_CHANGE; } }, GIVING_CHANGE(TRANSIENT) { public void next() { if (amount > 0) { System.out.println("变成" + amount); amount = 0; } state = RESTRING; } }, TERMINAL { void output() { System.out.println("终止"); } }; // 售货机在处理中 private boolean isTransient = false; // 使用构造函数巧妙的设置了状态是瞬时的还是持续的 private State() { } private State(StateDuration sd) { isTransient = true; } // 进入下一个状态 public void next() { throw new RuntimeException("不用实现"); } // 进入输入对应的下一个状态 public void next(Input input) { throw new RuntimeException("不用实现"); } void output() { System.out.println(amount); } } // 运行 public static void run(Generator<Input> gi) { // 没有显示终端则继续运行 while (state != State.TERMINAL) { state.next(gi.next()); // 瞬时状态继续运行 while (state.isTransient) { // 进入下一个状态 state.next(); } state.output(); } } public static void main(String args[]) { Generator<Input> gi = new RandomInputGenerator(); String fileName = "QUARTER;QUARTER;QUARTER;CHIPS;DOLLAR;DOLLAR;TOOTHPASTE;QUARTER;DIME;ABORT_TRANSACTION;QUARTER;DIME;SODA;QUARTER;DIME;NICKE;SODA;ABORT_TRANSACTION;STOP"; gi = new FileInputGenerator(fileName); run(gi); } } class RandomInputGenerator implements Generator<Input> { @Override public Input next() { return Input.randomSelect(); } } class FileInputGenerator implements Generator<Input> { //迭代器适合下一个 private Iterator<String> input; public FileInputGenerator(String fileName) { //数组转换为集合 集合转换为迭代器 input = Arrays.asList(fileName.split(";")).iterator(); } @Override public Input next() { if (input.hasNext()) { return Enum.valueOf(Input.class, input.next()); } return null; } }