java枚举介绍
枚举类的构造器只能使用private 访问控制符,如果省略了构造器的访问控制符,则默认使用private 修饰
枚举的所有实例必须在枚举类的第一行显示出,否则这个枚举类永远都不能产生实例
枚举类默认提供了values() 方法,该方法可以很方便的遍历所有的枚举值。
为什么要使用枚举而不适用static 关键字呢?
在某些情况下,一个类的对象时有限而且 是固定的,比如季节类 ,它只有4个对象,这种实例有限而且固定的类,在java中称为枚举
比如:以前定义
public static final int SEASON_SPRING = 1;
public static final int SEASON_SUMMER = 2;
public static final int SEASON_AUTUMN = 3;
public static final int SEASON_WINTER = 4;
存在以下问题:
类型不安全: 因为上面的每个季节实际上时一个int 整数,因此完全可以把一个季节当成一个int整数使用,例如进行加法运算SEASON_SPRING + SEASON_SUMMER,这样代码完全正常。
没有命名空间: 当需要使用季节时,必须在SPRING前使用SEASON_前缀,否则程序可能与其他类中的静态常量混淆。
打印输出的意义不明确:当输出某个季节时,例如输出SEASON_SPRING,实际 上输出的是1,这个1很难猜测它代表了春天
枚举的方法
values() 返回枚举中的所有值
oridinal() 方法可以找到每个枚举常量的索引,就像数组索引一样
valueOf()方法返回指定字符串值的枚举常量。
public enum SeasonEnum {
SPRING(1,"春天"), SUMMER(2,"夏天"), AUTUMN(3,"秋天"), WINTER(4,"冬天");
SeasonEnum(int index,String name){
this.index = index;
this.name= name;
}
private int index;
private String name;
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
//1. 迭代枚举值
for(SeasonEnum season: SeasonEnum.values()){
System.out.println(season);
}
//2.oridinal() 找到每个枚举常量的索引,就像数组索引一样
System.out.println(SeasonEnum.SPRING.ordinal());
//3.valueOf() 方法返回指定字符串值的枚举常量
System.out.println(SeasonEnum.valueOf("SPRING"));
}
}
枚举的基本用法
用作常量
public enum SeasonEnum {
SPRING, SUMMER, AUTUMN , WINTER;
}
用在Switch中
public enum SeasonEnum {
SPRING, SUMMER, AUTUMN , WINTER;
}
public class SeasonEnumtest {
SeasonEnum seasonEnum;
public SeasonEnumtest(SeasonEnum seasonEnum){
this.seasonEnum = seasonEnum;
}
public void tellMeSeason(){
switch (seasonEnum){
case SPRING:
System.out.println("这时春天..");
break;
case SUMMER:
System.out.println("这是夏天...");
break;
case AUTUMN:
System.out.println("这是秋天...");
break;
case WINTER:
System.out.println("这是冬天...");
break;
}
}
public static void main(String[] args) {
SeasonEnumtest seasonEnumtest = new SeasonEnumtest(SeasonEnum.SPRING);
seasonEnumtest.tellMeSeason();
}
}
自定义属性
public enum SeasonEnum {
SPRING(1,"春天"), SUMMER(2,"夏天"), AUTUMN(3,"秋天"), WINTER(4,"冬天");
SeasonEnum(int index,String name){
this.index = index;
this.name= name;
}
private int index;
private String name;
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
包含抽象方法的枚举类
假设有一个Operation枚举类,它的4个枚举值 PLUS,MUNUS,TIMES,DIVIDE 分别代表加减乘除4中运算,该枚举需要定义一个eval方法完成计算。Operation 需要让 PLUS MINUS TIMES DIVIDE 四个值对eval() 方法各种不同的实现。此时可以考虑定义一个evel() 抽象方法,然后让4个枚举值分别为 eval() 提供不同的实现,代码如下:
public enum Operation {
PLUS{
@Override
double eval(double x, double y) {
return x+y;
}
},MINUS{
@Override
double eval(double x, double y) {
return x-y;
}
},TIMES{
@Override
double eval(double x, double y) {
return x*y;
}
},DIVIDE{
@Override
double eval(double x, double y) {
return x/y;
}
};
//为枚举类定义一个抽象方法
// 这个抽象方法由不同的枚举值提供不同的实现
abstract double eval(double x,double y);
public static void main(String[] args) {
System.out.println(Operation.PLUS.eval(3,4));
System.out.println(Operation.MINUS.eval(5,4));
System.out.println(Operation.TIMES.eval(5,4));
System.out.println(Operation.DIVIDE.eval(5,4));
}
}
枚举类里定义抽象方法时不能使用abstract关键字将枚举定义成抽象类(因为系统会为它添加abstract关键字),但因为枚举类需要显示创建枚举值,而不是作为父类,所以定义每个枚举值时必须为抽象方法提供实现,否则将出现编译错误。
实现接口的枚举类
public interface Gender {
void info();
}
public enum GenderEnum implements Gender{
MALE("男"){
@Override
public void info() {
System.out.println("这个枚举值代表男性...");
}
},
FEMAIL("女"){
@Override
public void info() {
System.out.println("这个枚举值代表女性...");
}
};
private String name;
GenderEnum(String name){
this.name = name;
}
}