【Java面向对象】5-10 枚举类
§5-10 枚举类
本节将介绍 Java 中一种特殊的类:枚举类。
5-11.1 理解与定义枚举类
枚举类(enumeration)是一种特殊的类,一般表示一组常量。例如四季、月份、星期、方向等。
枚举类的对象是有限、确定的。当需要一组常量时,强烈建议使用枚举类。
自 JDK 5.0 后,可以通过使用关键字 enum
定义枚举类。
5-11.1.1 JDK 5.0 前自定义枚举
JDK 5.0 前,可以通过使用 class
定义枚举。
为了体现枚举类中对象有限、确定的特点,必须私有化构造器,且成员属性常量化。
public class Season {
//声明属性,使用private final修饰
private final String seasonName;
//私有化构造器,使得对象个数确定
private Season(String seasonName) {
//在构造器中为属性赋值,初始化常量
this.seasonName = seasonName;
}
//创建对象,使用public static final修饰
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("冬天");
}
至此,自定义枚举完成。若有其他需求,例如 Getter、打印为字符串,可以有:
public class Season {
//省略上述相同代码
//获取季节名字
public String geteasonName() {
return seasonName;
}
//打印为字符串
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
'}';
}
}
在主方法中测试:
public class Main {
public static void main(String[] args) {
Seasons spring = Seasons.SRPING;
System.out.println(spring);
}
}
可有:
LegacySeasons{seasonName='春天'}
5-11.1.2 JDK 5.0 后使用enum
关键字定义枚举类
使用 enum
关键字定义枚举类,首先应当把枚举对象列出。同样是季节枚举类,可以基于上述代码更改:
public enum Seasons {
//首先必须提供枚举对象,对象间用,隔开,默认为public static final
SPRING("春天"),
SUMMER("夏天"),
AUTUMN("秋天"),
WINTER("冬天");
//对象属性
private final String seasonName;
//构造器,默认为私有,private关键字可省略
Seasons(String seasonName) {
this.seasonName = seasonName;
}
//获取属性
public String getSeasonName() {
return seasonName;
}
//toString()方法继承自java.lang.Enum,不是Object,默认打印常量名字。可根据需求重写。
}
在主方法中测试:
public class Main {
public static void main(String[] args) {
Seasons autumn = Seasons.AUTMN;
System.out.println(autumn);
}
}
得到:
AUTUMN
5-11.2 枚举类中的常用方法
Enum
中有很多方法,这里,我们只关注三个重要方法。
5-11.2.1 values();
描述:返回一个含有该枚举类全部对象的数组,通常用于遍历枚举类。
例子:(以上述的 Seasons
为例,下同)
public class Main {
public static void main(String[] args) {
Seasons[] values = Seasons.values();
for (int i = 0; i < values.length; i++)
{
System.out.println(values[i]);
}
}
}
运行结果:
SPRING
SUMMER
AUTUMN
WINTER
5-11.2.2 valueOf(String objName);
描述:返回与 objName
同名的枚举对象。若找不到,则抛出异常 java.lang.IllegalArgumentException
。
例子:
public class Main {
public static void main(String[] args) {
Seasons winter = Seasons.valueOf("WINTER");
System.out.println(winter);
}
}
运行结果:
WINTER
1-11.2.3 ordinal();
描述:返回枚举常量声明中,该枚举常量的序数。
注意:第一个常量的序数为 0。
例子:
public class Main {
public static void main(String[] args) {
Seasons winter = Seasons.valueOf("WINTER");
System.out.println(winter.ordinal());
}
}
运行结果:
3
5-11.2.4 toString();
描述:将枚举对象转化成字符串,默认继承 java.lang.Enum
中的 toString();
方法,返回该对象的名字。
源码:(摘取部分)
public abstract class Enum<E extends Enum<E>>
implements Constable, Comparable<E>, Serializable {
/**
* The name of this enum constant, as declared in the enum declaration. Most programmers should use the toString() method rather than accessing this field.
*/
private final String name;
/**
* Returns the name of this enum constant, as contained in the declaration. This method may be overridden, though it typically isn't necessary or desirable. An enum class should override this method when a more "programmer-friendly" string form exists.
*/
public String toString() {
return name;
}
}
5-11.3 枚举类实现接口
同样地,枚举类也可以实现接口。枚举类实现接口的方法有两种。
5-11.3.1 在类内部重写抽象方法
还是以上文的 Seasons
枚举类为例,在该文件下定义一个接口 Info
:
interface Info {
void show();
}
和一半类实现接口一样,在枚举类中重写抽象方法:
public enum Seasons {
... //省略
@Override
public void show() {
System.out.println("这是一个季节。");
}
}
放在主方法中测试,通过任意一个枚举类对象调用该方法,都会得到
这是一个季节。
5.11.3.2 在对象中重写抽象方法
上一种实现方法,每一个枚举类对象调用时都会产生一样的结果。而在对象中分别重写抽象方法,可以使得方法调用与对象绑定(相关)。
public enum Seasons implements Info {
SPRING("春天") {
@Override
public void show() {
System.out.println("春暖花开。");
}
},
SUMMER("夏天") {
@Override
public void show() {
System.out.println("夏日炎炎。");
}
},
AUTUMN("秋天") {
@Override
public void show() {
System.out.println("秋高气爽。");
}
},
WINTER("冬天") {
@Override
public void show() {
System.out.println("凛冬已至。");
}
};
}
在主方法中有
Seasons autumn = Seasons.AUTUMN;
Seasons winter = Seasons.valueOf("WINTER");
autumn.show();
winter.show();
运行,得到结果:
秋高气爽。
凛冬已至。