Java枚举

引入

编写季节类(Season),该类只有四个对象(spring,summer,autumn,winter)

//季节类
public class Season {
	
	public static final Season spring = new Season("春天","万物复苏");
	public static final Season summer = new Season("夏天","烈日灼心");
	public static final Season autumn = new Season("秋天","秋高气爽");
	public static final Season winter = new Season("冬天","银装素裹");
	
	private String name;
	private String info;
	
	private Season() {
	}
	
	private Season(String name, String info){
		this.name = name;
		this.info = info;
	}

	public static Season getSpring() {
		return spring;
	}

	public static Season getSummer() {
		return summer;
	}

	public static Season getAutumn() {
		return autumn;
	}

	public static Season getWinter() {
		return winter;
	}

	@Override
	public String toString() {
		return "Season [name=" + name + ", info=" + info + "]";
	}
	
}

public static void main(String[] args) {
		/**
		 * 枚举引入:
		 * 编写季节类(Season),该类只有四个对象(spring,summer,autumn,winter)
		 */
		
		System.out.println(Season.spring);//Season [name=春天, info=万物复苏]
		System.out.println(Season.summer);
		System.out.println(Season.autumn);
		System.out.println(Season.winter);

}

概念

枚举(enum)全称为 enumeration, 是 JDK 1.5 中引入的新特性。

语法

public enum Color {
	//枚举中没有定义方法时,可以在最后一个对象后面加逗号、分号或什么都不加
//	RED,YELLOW,GREEN
//	RED,YELLOW,GREEN,
	RED,YELLOW,GREEN;
	
	//若定义了方法,则最后一个对象后面必须加上分号

}

本质

尽管枚举看起来像是一种新的数据类型,实际上,枚举就是一种受限制的类,并且具有自己的方法。创建自己的enum类时,这个类继承自 java.lang.Enum。

	public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable{
    ...
}

特点

  • 枚举就是一个受限制的类,默认继承Enum
  • 枚举的第一行必须定义该枚举类型的对象
  • 枚举类型对象默认添加: public static final 类型
  • 枚举没有继承明确类(自定义枚举类默认继承Enum,Enum默认继承Object)
  • 枚举类不能被继承
  • 枚举里可以有构造方法、成员方法、静态方法、抽象方法(通过匿名内部类实现)
  • 枚举可以实现接口
  • 枚举里没有定义方法,可以在最后一个对象后面加逗号、分号或什么都不加

优势

  • 增强代码可读性

  • 枚举型可直接与数据库交互

  • switch语句优势

  • 编译优势

    (枚举类编译时,没有把常量值编译到代码中,即使常量值发生改变,也不会影响引用常量的类 )

  • 将常量组织起来,统一管理

  • 去除equals两者判断 由于常量值地址唯一,使用枚举可以直接通过“==”进行两个值之间的对比,性能会有所提高

枚举的常用方法

方法名解释
Enum.valueOf(Class enumType, String name)根据字符串找到该枚举类中的对象
public static void values()获取该枚举类对象数组
public static void valueOf(String args0)根据字符串获取该枚举类中的对象
public final String name()获取该枚举对象名字
public final Class getDeclaringClass()获取枚举对象的枚举类型相对应的Class对象
public final int hashCode()获取该枚举对象的hash值
public final int compareTo(E o)两个枚举对象进行比较
public final boolean equals(Object other)比较两个枚举对象是否相同
//底层实现:public class Season extends Enum
public enum Season {
	
	//默认添加:public static final Season
	spring("春天","万物复苏"),
	summer("夏天","烈日灼心"),
	autumn("秋天","秋高气爽"),
	winter("冬天","银装素裹");
	
	private String name;
	private String info;
	
	private Season() {
	}

	private Season(String name, String info) {
		this.name = name;
		this.info = info;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getInfo() {
		return info;
	}

	public void setInfo(String info) {
		this.info = info;
	}
	
	@Override
	public String toString(){
		return name + "---" + info;
	}
	
}

//枚举的常用方法
public static void main(String[] args) {

       //通过字符串获取枚举的对象
       Season season1 = Enum.valueOf(Season.class, "spring");
       System.out.println(season1);

       //获取Season枚举类中所有对象
       Season[] values = Season.values();
       for (Season season : values) {
           System.out.println(season);
       }

       //通过字符串获取枚举的对象
       Season season2 = Season.valueOf("winter");
       System.out.println(season2);

       //获取枚举对象的名字
       String name = season2.name();
       System.out.println(name);

       //获取Season枚举类的字节码文件对象
       Class<Season> c = season2.getDeclaringClass();
       System.out.println(c);

}

枚举案例

状态机
enum Signal{RED, YELLOW, GREEN}

public class EnumTest {

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		
		System.out.println("请输入信号灯:RED,YELLOW,GREEN");
		Signal signal = Signal.valueOf(scan.next());
        
		String instruct = getTrafficInstruct(signal);
		System.out.println(instruct);
		
		scan.close();
	}

    public static String getTrafficInstruct(Signal signal) {
        String instruct = "信号灯故障";
        switch (signal) {
            case RED:
                instruct = "红灯停";
                break;
            case YELLOW:
                instruct = "黄灯请注意";
                break;
            case GREEN:
                instruct = "绿灯行";
                break;
            default:
                break;
        }
        return instruct;
    }
}
错误码
public enum ErrorCodeEn {
	
	Ok(1,"成功"),ERROR_A(2,"错误A"),ERROR_B(3,"错误B");
	
	private int code;//状态码
	private String description;//状态信息
	
	ErrorCodeEn(){}
	
	ErrorCodeEn(int code,String description){
		this.code = code;
		this.description = description;
	}

	public int getCode() {
		return code;
	}

	public String getDescription() {
		return description;
	}
}
组织枚举

含义:使用类或者接口把众多的枚举组织起来
经验:一般使用接口组织
原因:
Java接口在编译时会自动为enum类型加上public static修饰符
Java类在编译时会自动为 enum 类型加上static修饰符
即在类组织中,如果不主动为enum加上public,那么就只能在本包中运行

public interface IErrorCode {

	enum LoginErrorCodeEn implements INumberEnum{

		OK(1,"登录成功"),ERROR_A(-1,"验证码错误"),ERROR_B(-2,"密码错误"),ERROR_C(-3,"用户已登录");

		private int code;
		private String description;

		LoginErrorCodeEn(int code,String description){
			this.code = code;
			this.description = description;
		}

		@Override
		public int getCode() {
			return code;
		}
		@Override
		public String getDescription() {
			return description;
		}
	}

	enum RigsterErrorCodeEn implements INumberEnum{

		OK(1,"注册成功"),ERROR_A(-1,"账号已存在");

		private int code;
		private String description;

		RigsterErrorCodeEn(int code,String description){
			this.code = code;
			this.description = description;
		}

		@Override
		public int getCode() {
			return code;
		}
		@Override
		public String getDescription() {
			return description;
		}
	}

}

interface INumberEnum {
	int getCode();
	String getDescription();
}
策略枚举

优点:这种枚举通过枚举嵌套枚举的方式,将枚举常量分类处理。

这种做法虽然没有switch语句简洁,但是更加安全、灵活。

public static void main(String[] args) {

    /**
		 * 枚举案例:策略枚举
		 * 
		 * 需求:计算学校所有员工的工资
		 * 分析:
		 * 		员工分类:行政人员、教师
		 * 		行政人员:基本工资 + 绩效
		 *		教师:基本工资 + 课时费*课时 + 绩效 
		 */
    double salary1 = Salary.java.getSalary(1800, 88, 15, 400);
    System.out.println(salary1);

    double salary2 = Salary.principal.getSalary(20000, 0, 0, 20000);
    System.out.println(salary2);

    double salary3 = Salary.reception.getSalary(1200, 0, 0, 200);
    System.out.println(salary3);
}

enum Salary{
	java(StaffType.teacher),//java部门
	python(StaffType.teacher),
	principal(StaffType.administrative),//总经办(校长)部门
	reception(StaffType.administrative);//前台部门
	private StaffType staffType;
	
	private Salary(StaffType staffType) {
		this.staffType = staffType;
	}
	
	public double getSalary(double baseSalary, int classHour, double teachingHourSubsidy,
			double achievements){
		return staffType.calculationSalary(baseSalary, classHour, teachingHourSubsidy, achievements);
	}
	
	enum StaffType{
		//匿名内部类对象
		administrative{//行政人员
			@Override
			public double calculationSalary(double baseSalary,int classHour,double teachingHourSubsidy,double achievements){
				BigDecimal bigBaseSalary = new BigDecimal(String.valueOf(baseSalary));
				BigDecimal bigAchievements = new BigDecimal(String.valueOf(achievements));
				BigDecimal bigDecimal = bigBaseSalary.add(bigAchievements);
				return bigDecimal.doubleValue();
			}
		},
		teacher{
			@Override
			public double calculationSalary(double baseSalary,int classHour,double teachingHourSubsidy,double achievements){
				BigDecimal bigBaseSalary = new BigDecimal(String.valueOf(baseSalary));
				BigDecimal bigClassHour = new BigDecimal(classHour);
				BigDecimal bigTeachingHourSubsidy = new BigDecimal(teachingHourSubsidy);
				BigDecimal bigAchievements = new BigDecimal(String.valueOf(achievements));
				BigDecimal bigDecimal =bigClassHour.multiply(bigTeachingHourSubsidy).add(bigBaseSalary).add(bigAchievements);
				return bigDecimal.doubleValue();
			}
		};
		
		//计算工资
		public abstract double calculationSalary(double baseSalary,int classHour,double teachingHourSubsidy,double achievements); 
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值