java基础总结 --- enum枚举的常量相关方法、自动售货机(状态模式)例子

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;
	}

}


你可能感兴趣的:(java基础总结 --- enum枚举的常量相关方法、自动售货机(状态模式)例子)