Java之枚举类

一、枚举类的概念

在某些情况下,一个类的对象是有限且固定的,比如季节类,它只有4个对象;再比如性别类,它只有两个对象。这种实例有限且固定的类,在Java中被称为枚举类。

枚举类实际上是一种特殊的类,它由关键字enum定义(与class、interface关键字地位相同),可以有自己的Field、方法、可以实现一个或者多个接口,也可以定义自己的构造器(只能是私有的)。

一个Java源文件中最多只能定义一个public访问权限的枚举类,且该Java源文件也必须和该枚举类的类名相同,编译之后会生成同名的class文件。

二、枚举类与普通类的区别

  • 枚举类可以实现一个或多个接口,使用enum定义的枚举类默认继承了java.lang.Enum类,而不是继承Object类。
  • 使用enum定义、非抽象的枚举类默认会使用final修饰 ,因此枚举类不能派生子类。
  • 枚举类的构造器只能使用private访问控制符,如果省略了构造器的访问控制符,则默认使用private修饰;如果强制指定访问控制符,则只能指定private修饰符。
  • 枚举类的所有实例必须在枚举类的第一行显式列出,否则这个枚举类永远都不能产生实例。列出这些实例时,系统会自动添加public static final修饰,无须程序员显式添加。
public enum Season{
    //在第一行列出4个枚举实例,以,分隔
    SPRING,SUMMER,FALL,WINTER;	//静态常量一般大写
}

三、在switch中使用枚举类

如果需要使用某个枚举类的某个实例,则可使用EnumClass.variable的形式,但在switch中可以直接使用枚举值

public class EnumClass{
    public void judge(Season s){
		//switch语句里的表达式可以是枚举值
        switch(s){
            case SPRING : System.out.println("春天");break; 
            case SUMMER : System.out.println("夏天");break;
            case SUMMER : System.out.println("秋天");break;
            case SUMMER : System.out.println("冬天");
        }
    }
    
    public static void main(String[] args){
        for(Season s : Season.values()){
            System.out.println(s);	//可以直接打印枚举值
        }
        //平常使用枚举实例时
        //总是通过EnumClass.variable的形式来访问
        new EnumClass().judge(Season.SPRING);
    }
}

该类通过values方法返回了Season枚举类的所有实例,并通过循环迭代输出了Season枚举类 的所有实例。

四、枚举类的Field、方法和构造器(不常用)

枚举类也是一种类,只是它是一种比较特殊的类,因此它一样可以定义Field、方法。只不过枚举类通常会被设计为不可变类,所以,我们应该将枚举类的Field都使用private final修饰,这样代码更安全且简洁。

public enum Gender{
	//此处的枚举值必须调用对应的构造器来创建
    //如果没有无参构造器,列出枚举值是就必须传入参数
    MALE("男"),FEMALE("女");
    private final String name;
    
    //枚举类的构造器只能使用private修饰,默认也是private
    private Gender(String name){
        this.name = name;
    }
    
    public String getName(){
        return this.name;
    }
}

从此例可知,在枚举类中列出枚举值时,实际上就是调用构造器创建枚举类对象,只是这里无须使用new关键字,也无须显式调用构造器。上面那个Season中列出枚举值时无须传入参数,甚至无须使用括号,是因为其中包含默认的无参构造器。

五、实现接口的枚举类(不常用)

枚举类也可以实现一个或多个接口

public interface GenderDesc{
    void showInfo();
}
public enum Gender implements GenderDesc{
	//其他部分与四中的Gender一样
    ...
   	//实现接口中的showInfo方法
    public void showInfo(){
        System.out.println("枚举类");
    }
}

如果由枚举类来实现接口里的方法,每个枚举值在调用该方法时都有相同的行为方式(因为方法体一样)。如果需要每个枚举值在调用该方法时呈现不同的行为方式时,可以在*公共实现方法中使用switch(this)*做判断或者每个实例分别实现该方法。

注: switch(this)比较推荐,因为实例多的情况,没开写代码冗余太高。实例少的情况,推荐分开实现

public enum Gender implements GenderDesc{
    //此处的枚举值必须调用对应的构造器来创建
    MALE("男"){	//花括号这是匿名内部类的写法
    	public void showInfo(){
        	System.out.println("男性的枚举方法");
    	}
    }
    
    FEMALE("女"){	
    	public void showInfo(){
        	System.out.println("女性的枚举方法");
    	}
    }
}    

这里就是分开实现,不推荐这种写法,更推荐switch判断

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章