二.枚举
枚举引入:
编写季节类(Season),该类只有四个对象(spring,summer,autumn,winter)Season必须私有化构造器
package com.dream.enum01;
public class Test01 {
public static void main(String[] args) {
System.out.println(Season.spring);
System.out.println(Season.summer);
System.out.println(Season.autumn);
System.out.println(Season.winter);
}
}
package com.dream.enum01;
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 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 "Season [name=" + name + ", info=" + info + "]";
}
}
//使用枚举解决这个需求
package com.dream.enum02;
public class Test01 {
public static void main(String[] args) {
System.out.println(Season.spring);
System.out.println(Season.summer);
System.out.println(Season.autumn);
System.out.println(Season.winter);
}
}
package com.dream.enum02;
//底层实现: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;
}
}
概念:
枚举(enum)全称为 enumeration, 是 JDK 1.5 中引入的新特性。
语法:
public enum Color{
//默认添加 public static final Color
RED,GREEN,BLUE;
}
本质:
尽管枚举看起来像是一种新的数据类型,实际上,枚举就是一种受限制的类,并且具有自己的方法。创建自己的enum类时,这个类继承自 java.lang.Enum。
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable{
...
}
特点:
- 枚举就是一个受限制的类,默认继承Enum
- 枚举的第一行必须定义该枚举类型的对象
- 枚举类型对象默认添加: public static final 类型
- 枚举没有继承明确类(自定义枚举类默认继承Enum,Enum默认继承Object)
- 枚举类不能被继承
- 枚举里可以有构造方法、成员方法、静态方法、抽象方法
- 枚举可以实现接口
- 枚举里没有定义方法,可以在最后一个对象后面加逗号、分号或什么都不加
package com.dream.enum02;
public enum Color {
//枚举里没有定义方法,可以在最后一个对象后面加逗号、分号或什么都不加
// RED,GREEN,BLUE
// RED,GREEN,BLUE,
RED,GREEN,BLUE;
}
优势:
增强代码可读性
枚举型可直接与数据库交互
switch语句优势
编译优势
(枚举类编译时,没有把常量值编译到代码中,即使常量值发生改变,也不会影响引用常量的类 )
将常量组织起来,统一管理
去除equals两者判断 由于常量值地址唯一,使用枚举可以直接通过“==”进行两个值之间的对比,性能会有所提高
枚举的方法:
public class Test02 {
public static void main(String[] args) {
//枚举中的常用方法
//通过字符串获取到枚举类中的对象
Season valueOf = Enum.valueOf(Season.class,"spring");
System.out.println(valueOf);
System.out.println("-------------");
//获取到Season枚举类中所有的对象
Season[] values = Season.values();
for (Season season : values) {
System.out.println(season);
}
System.out.println("-------------");
//通过字符串获取到枚举类中的对象
Season valueOf2 = Season.valueOf("summer");
System.out.println(valueOf2);
}
}
案例:
状态机
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();
}
策略枚举
package com.dream.enum07;
import java.math.BigDecimal;
public class Test01 {
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),//python部门
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 big = bigBaseSalary.add(bigAchievements);
return big.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(String.valueOf(classHour));
BigDecimal bigTeachingHourSubsidy = new BigDecimal(String.valueOf(teachingHourSubsidy));
BigDecimal bigAchievements = new BigDecimal(String.valueOf(achievements));
BigDecimal big = bigClassHour.multiply(bigTeachingHourSubsidy).add(bigBaseSalary).add(bigAchievements);
return big.doubleValue();
}
};
//计算工资
public abstract double calculationSalary(double baseSalary,int classHour,double teachingHourSubsidy,double achievements);
}
}