问题引入
为了将某一数据类型的值限定在可选的合理范围内,比如季节只有四个:春夏秋冬。
什么是枚举类
Java5之后新增了enum关键字(他与class,interface关键字地位相同)用来定义枚举类,他是一个特殊的类。
可以有自己的:成员变量、方法、构造器。可以实现一个或多个接口。
一个Java源文件中最多只能定义一个public访问权限的枚举类,且改Java原文件必须和该枚举类的类名相同。
和普通类的简单区别:
1、默认继承的是java.lang.Enum类,非Object。因此不能显示的 继承其他父类。其中java.lang.Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口
2、非抽象的枚举类型默认都是final修饰,因此枚举类不能派生子类。
3、枚举类的构造器只能使用private访问控制权限。省略默认private,强制写只能写private
4、枚举类的所有实例值,必须再枚举类的第一行显式罗列出,否则这个枚举类用用无法产生实例。这些实例默认public static final修饰。无需程序员添加。
自定义枚举类
代码示例:定义季节枚举类,限定春夏秋冬四个值
package com.zmd.study.enum_example; /** * @ClassName SeasonEnum * @projectName: object1 * @author: Zhangmingda * @description: 定义一个季节的枚举类,春夏秋冬 * date: 2021/4/3. */ public enum SeasonEnum { SPRING, SUMMER, FALL, WINTER; }
查看枚举类的值.values()
package com.zmd.study.enum_example; import com.sun.org.apache.xerces.internal.dom.PSVIAttrNSImpl; /** * @ClassName SeasonEnumTest * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/4/3. */ public class SeasonEnumTest { public static void main(String[] args) { //打印季节枚举类的值有哪些 for(SeasonEnum seasonEnum : SeasonEnum.values()){ System.out.println(seasonEnum); } //应用场景,定义枚举变量,做switch case判断 SeasonEnum seasonEnum = SeasonEnum.SPRING; switch (seasonEnum){ case SPRING: System.out.println("春天"); break; case SUMMER: System.out.println("夏天"); break; case FALL: System.out.println("秋天"); break; case WINTER: System.out.println("冬天"); break; default: System.out.println("季节输入错误"); } } }
输出
SPRING
SUMMER
FALL
WINTER
春天
枚举类 的自带方法
1、对比方法compreTo()
本身相对比初始纳入的参数的位置,例如春天SPRING比秋天FALL 提前2个位置定义,用春天对比秋天就是-2
//枚举类值的对比 System.out.println(SeasonEnum.SPRING.compareTo(SeasonEnum.FALL)); //-2
2、name()方法获取对应值的名称
//获取名字,就是对应值的字符串 System.out.println(SeasonEnum.SPRING.name());
//这个就是输出SPRING
3、ordinal()获取值在枚举类中定义的顺序
//获取值在枚举类中定义的顺序 System.out.println(SeasonEnum.SPRING.ordinal()); //第0位输出0; 顺序从0开始...
4、Enum.valueOf()获取对应类型指定名字的枚举
//获取对应枚举类型,对应名字的枚举 SeasonEnum season_fall = Enum.valueOf(SeasonEnum.class,"FALL"); System.out.println(season_fall);
5、成员变量、普通方法、构造方法
成员变量常用的比如name ,生产中用来释义对应的中文释义。
定义枚举值的时候直接将实例的成员变量通过构造方法赋值,例如SPRING("春天"),就是构造了一个枚举类型值,同时定义好了成员变量name。使用的时候可以直接调用getName()获取定义的name变量.
示例:季节类
package com.zmd.study.enum_example; /** * @ClassName SeasonEnum * @projectName: object1 * @author: Zhangmingda * @description: 定义一个季节的枚举类,春夏秋冬 * date: 2021/4/3. */ public enum SeasonEnum { SPRING("春天"), SUMMER("夏天"), FALL("秋天"), WINTER("冬天"); private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } SeasonEnum(String name) { this.name = name; } }
测试含有构造方法的枚举类
public class SeasonEnumTest { public static void main(String[] args) { //测试枚举类的构造方法 System.out.println(SeasonEnum.SPRING.getName()); } }
枚举类可以实现接口
比如如上季节的枚举类,实现一个用来获取对应值描述的接口Info。
package com.zmd.study.enum_example; public interface Info { void info(); }
季节枚举类,在构造值的过程重写接口的抽象方法 info()
格式:
枚举值(构造方法传参){重写接口的抽象方法}
package com.zmd.study.enum_example; /** * @ClassName SeasonEnum * @projectName: object1 * @author: Zhangmingda * @description: 定义一个季节的枚举类,春夏秋冬 * date: 2021/4/3. */ public enum SeasonEnum implements Info{ SPRING("春天"){ @Override public void info() { System.out.println("这是春天");; } }, SUMMER("夏天"){ @Override public void info() { System.out.println("这是夏天");; } }, FALL("秋天"){ @Override public void info() { System.out.println("这是秋天"); } }, WINTER("冬天"){ @Override public void info() { System.out.println("这是冬天"); } }; private String name; public String getName() { return name; } // public void setName(String name) { // this.name = name; // } SeasonEnum(String name) { this.name = name; } @Override public void info() { System.out.println("这是一个季节枚举类"); } }
包含抽象方法和静态方法的枚举类
例如一个数学的四则运算枚举类。实现两个数的加减乘除四个值,每个值都有自己的“运算”逻辑,可以重写(共用)上一级的抽象“运算”方法
可以包含运算的抽象方法,每种运算各自通过自己的运算规则实现运算的抽象方法。
本例:抽象方法eval() 、静态方法main()。
package com.zmd.study.enum_example; /** * @ClassName Operation * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/4/5. */ public enum Operation { //加减乘除四种数学运算方法,每种方法重写了"运算" 方法 PLUS{ @Override public double eval(double a, double b) { return a + b; } }, MINUS{ @Override public double eval(double a, double b) { return a - b; } }, TIMES{ @Override public double eval(double a, double b) { return a * b; } }, DEVIDE{ @Override public double eval(double a, double b) { return a / b; } }; //做运算的抽象方法 public abstract double eval(double a, double b); //可以枚举类可以包含静态方法,例如main方法 public static void main(String[] args) { double d = Operation.PLUS.eval(1,3); System.out.println(d); } }
如上示例:1+3 输出4.0