枚举类
1、手动实现枚举类
public class SeasonDemo {
public static final int SEASON_SPRING=1;
public static final int SEASON_SUMMER=2;
public static final int SEASON_FAIL=3;
public static final int SEASON_WINTER=4;
}
缺点:
- 类型不安全:每一个季节的值均为int类型,季节可以被当做整数使用。
- 没有命名空间:当需要使用季节时,必须使用SEASON前缀,易与混淆其他静态常量混淆。
- 打印输出的意义不明确:System.out.println(SeasonDemo.Season);输出出的结果是1, 很难猜测1代表春天。
JDK1.5之前,采用类定义的方式实现。方法如下
★通过private将构造器隐藏起来(避免创建对象的随意性,只允许类内创建对象)
★ 把这个类的所有可实例都以public static final 修饰的类变量来保存
★如果有必要,可以提供一些静态方法,允许程序根据特定的参数来获取与之匹配的实例
public class Season
{
// 把Season类定义成不可变的,将其成员变量也定义成final的
private final String name;
private final String desc;
public static final Season SPRING
= new Season("春天" , "趁春踏青");
public static final Season SUMMER
= new Season("夏天" , "夏日炎炎");
public static final Season FALL
= new Season("秋天" , "秋高气爽");
public static final Season WINTER
= new Season("冬天" , "围炉赏雪");
public static Season getSeason(int seasonNum)
{
switch(seasonNum)
{
case 1 :
return SPRING;
case 2 :
return SUMMER;
case 3 :
return FALL;
case 4 :
return WINTER;
default :
return null;
}
}
// 将构造器定义成private访问权限
private Season(String name , String desc)
{
this.name = name;
this.desc = desc;
}
// 只为name和desc提供getter方法
public String getName()
{
return this.name;
}
public String getDesc()
{
return this.desc;
}
}
2、枚举类入门
java5之后增加了关键字enum,它与class、interface的地位相同,用来定义枚举类。
枚举类是一种特殊的类,一样可以有自己的构造器、成员变量、方法,也可以实现一个或多个接口。
枚举类的特点
▲枚举类可以实现一个或者多个接口,使用enum定义的枚举类默认的继承了java.lang.Enum类,而不是默认的继承Object,因此枚举类不能在继承其他父类。其中,java.lang.Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口。
▲使用enum定义的非抽象枚举类不能派生子类。(enum创建的非抽象枚举类,默认采用final修饰,抽象枚举类,系统默认采用abstract修饰)
▲枚举类的构造器只能采用private修饰(默认private)
▲枚举类的实例必须在枚举类的第一行显示列出,否则这个枚举类永远无法产生实例。列出这些是实例时,系统会自动的添加public static final 修饰,无需程序员显式的添加
// SeasonEnum.java
public enum SeasonEnum {
SPRING,SUMMER,FAIL,WINTER;
}
//EnumTest.java
public class EnumTest {
//判断枚举类型的值
//形参直接使用枚举类型
public void judge(SeasonEnum s){
switch (s){
case SPRING: System.out.println("春天到了");break;
case SUMMER:System.out.println("夏天到了");break;
case FAIL: System.out.println("秋天到了");break;
case WINTER: System.out.println("冬天到了");break;
}
}
public static void main(String args[]){
//遍历枚举类,枚举类默认有values()方法
for (SeasonEnum s:SeasonEnum.values()){
System.out.println(s);
}
//调用judge()函数判断季节
EnumTest e=new EnumTest();
e.judge(SeasonEnum.SPRING);
e.judge(SeasonEnum.SUMMER);
e.judge(SeasonEnum.FAIL);
e.judge(SeasonEnum.WINTER);
}
}
所有枚举类默认都继承了java.lang.Enum类,所有的枚举类可以直接使用java.lang.Enum类中包含的方法。java.lang.Enum类中提供了如下几个方法
3、枚举类的构造器、成员变量、方法
■构造器
public enum Gender {
//此处的枚举值,通过构造器来创建
/*
当为Gender枚举类创建一个Gender(String name)构造器之后,
应采用下面的方式。在枚举类列举枚举值时,实际上就是调用
构造器创建枚举类对象,只不过这里无需使用new关键字,也无需
现式的调用构造器
等价于
public static fianl Gender MALE=new Gender("男");
public static fianl Gender FEMALE=new Gender("女");
*/
MALE("男"),FEMAL("女");
//成员变量设计成不可变类型 private final
private final String name;
private Gender(String name){
this.name=name;
}
//不设计set方法。
public String getName() {
return this.name;
}
}
■成员变量
成员变量设计成不可变类型 private final
■方法
不设计set方法。
4、让枚举类实现节口
枚举类也可以实现一个或多个接口。与普通类实现节口一样,枚举类实现一个或者多个接口时,也需要实现该接口所包含的方法。
定义接口
public interface GenderDesc {
void info();
}
public enum Gender implements GenderDesc {
MALE("男"),FEMAL("女") ;
//重写了interface的方法
@Override
public void info() {
System.out.println("这是一个用于定义性别的枚举类");
}
private final String name;
private Gender(String name){
this.name=name;
}
public String getName() {
return this.name;
}
}
如果由枚举类实现接口里的方法,则每个枚举值在调用该方法时都有相同的行为方式(因为方法体完全一样)。如果需要每个枚举值在调用该方法时,显现出不同的行为方式,则可以让每个枚举值提供不同的实现方式。
如下所示,在上面的基础上,让每个枚举值分别对应不同的info()方法
public enum Gender implements GenderDesc {
/*
花括号部分实际上就是一个匿名内部类,在这种情况下,当创建MALE,FEMAL枚举值时,并不是直接创建Gender枚举类的实例,而是相当于相当于创建Gender的匿名子类的实例
*/
MALE("男") {
public void info(){
System.out.println("这个枚举值代表男");
}
},
FEMAL("女"){
public void info(){
System.out.println("这个枚举值代表女");
}
}
;
private final String name;
private Gender(String name){
this.name=name;
}
public String getName() {
return this.name;
}
}
5、包含抽象方法的枚举类
枚举类中有抽象方法时不能使用abstract关键字,因为系统会自动添加abstract关键字
public enum Operation
{
PLUS
{
public double eval(double x , double y)
{
return x + y;
}
},
MINUS
{
public double eval(double x , double y)
{
return x - y;
}
},
TIMES
{
public double eval(double x , double y)
{
return x * y;
}
},
DIVIDE
{
public double eval(double x , double y)
{
return x / y;
}
};
// 为枚举类定义一个抽象方法
// 这个抽象方法由不同的枚举值提供不同的实现
public 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));
}
}