枚举类

Posted yumiaoxa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了枚举类相关的知识,希望对你有一定的参考价值。

 在某些情况下,有些类的对象是有限和固定的比如季节类,它只有4个对象,再比如行星类,只有8个对象。这种实例有限而且固定的类,在Java里被称为枚举类。在一个Java源文件中,最多只能定义一个public访问权限的枚举类,且该源文件也必须和该枚举类的类名相同

一. 枚举类入门

java 5新增了一个enum关键字(相当于class,interface)来定义枚举类。枚举类是一种特殊的类与普通类有些简单区别。

  • 枚举类可以实现一个或多个接口,使用enum定义的枚举类默认继承了java.lang.Enum类,而不是继承Object类,因此枚举类不能显式继承其他父类。其中java.lang.Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口。
  • 使用enum定义,非抽象的枚举类默认会使用final修饰,因此枚举类不能派生子类
  • 枚举类的构造器只能使用private访问控制符 ,默认使用private控制符,可省略不写
  • 枚举类的所有实例必须在枚举类的第一行显式指出,否则这个枚举类永远都不能产生实例。列出这些实例时,系统会自动添加public static final修饰无需程序显式添加
  • 枚举类默认提供了一个value()方法,该方法可以很方便的遍历所有的枚举值

下面定义了一个SesssionEnum枚举类

public enum SeasonEnum
{
SPRING,SUMMER,FALL,WINTER;

}

如果需要使用该枚举类的某个实例,则可使用Enumclass.variable的形式,如SessionEnum.SPRING。

package com.gdut.enumTest;

public class EnumTest {
    public void judge(SeasonEnum s) {
//jdk1.5增加了swich表达式的拓展,表达式可以是任何枚举类型
switch (s) { case SPRING:System.out.println("春暖花开,正好踏青"); break; case SUMMER:System.out.println("夏日炎炎,适合游泳"); break; case FALL:System.out.println("秋高气爽,进补及时"); break; case WINTER:System.out.println("大雪飘飘,围炉赏雪"); break; } } public static void main(String[] args) { for(SeasonEnum s : SeasonEnum.values()) { System.out.println(s); } //使用枚举类实例时,可通过EnumClass.variable形式来访问 new EnumTest().judge(SeasonEnum.SPRING); } }

所有枚举类都继承了java.lang.Enum类,所以枚举类都可以使用java.lang.Enum的方法

  • int compareTo(E o):该方法用于指定枚举对象比较顺序,同一个枚举实例只能与相同类型的枚举实例进行比较。如果该枚举对象在指定枚举对象之后,则返回正整数;如果该枚举对象在指定枚举对象之前,则返回负整数;否则返回0。
  • String name:返回枚举实例名称,与toString()方法作用相当。
  • int ordinal():返回枚举值在枚举类中的索引值。
  • String toString():返回枚举实例名称,比name方法更常用
  • public static <T extends Enum<T>> T valueOf(Class<T> enumType,String name):返回指定枚举类中指定名称的枚举值

上面程序打印的时候实际上调用了toString()方法,输出枚举值的名字

二. 枚举类的成员变量,方法,构造器

枚举类也是以种类,是一种特殊的类,它一样可以定义成员变量、方法和构造器。

package com.gdut.enumTest;

public enum Gender {
    MALE,FEMALE;
    public String name;
}
package com.gdut.enumTest;

public class GenderTesst {

    public static void main(String[] args) {
        Gender g = Enum.valueOf(Gender.class, "FEMALE");
        g.name = "女";
        System.out.println(g+"代表:"+g.name);
    }

}

上面程序使用枚举类时与使用一个普通类没有太大差别,只是产生Gender对象的方式不同。枚举类的实例只能是枚举值,而不是随意通过new来创建枚举类对象。

下面程序通过方法来控制对name的访问

package com.gdut.enumTest;

import java.util.IllegalFormatCodePointException;

public enum Gender {
    MALE,FEMALE;
    private String name;
    
    public void setName(String name) {
        switch (this) {
        case MALE:
            if(name.equals("男")) this.name = name;
            else System.out.println("参数错误");
            break;
        case FEMALE:
            if(name.equals("女")) this.name = name;
            else System.out.println("参数错误");
            break;
            
  
        default:
            break;
        }
    }
}

实际上这种做法依然不够好,枚举类通常应该设计为不可变类,也就是说,他的变量值不应该允许改变,这样会更安全。因此建议枚举类的成员变量使用private final修饰。

如果所有的成员变量都是用final修饰,则必须在构造器里为这些成员变量指定初始值(或者再定义时或初始块中指定,但这两种情况不常见),因此应该为枚举类显式指定带参数的构造器。

package com.gdut.enumTest;

public enum Gender {
    MALE("男"),FEMALE("女");
    private String name;
    
    private Gender(String name) {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
}

三. 实现接口的枚举类

如果由枚举类实现接口里的方法,则每个枚举值在调用该方法时都有相同的行为方式(因为方法体完全一样)。如果需要每个枚举值在调用该方法时呈现不同的行为方式,则可让每个枚举值

分别实现该方法。

package com.gdut.enumTest;

interface GenderDesc{
    void info();
}

public enum Gender implements GenderDesc{
    MALE("男"){
        @Override
        public void info() {
            System.out.println("这个枚举值代表男性");
        }
        
    },FEMALE("女"){
        @Override
        public void info() {
            System.out.println("这个枚举值代表男女性");
        }
        
    };
    
    private String name;
    
    private Gender(String name) {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }

    
}

便宜上面的程序,可看到生成Gender.class,Gender$1.class,Gender$2.class三个文件,证明了MALE和FEMALE实际上是Gender类的匿名子类的实例,而不是Gender类的实例。                                   四. 包含抽象方法的枚举类

假设一个枚举类Operation包含四个实例:PLUS,MINUS,TIMES,DIVIDE分别代表加减乘除4种运算,该枚举类需要定义一个eval()抽象方法来完成计算。

package com.gdut.enumTest;

public enum Operation {
PLUS(){
    @Override
    public double eval(double num1, double num2) {
        return num1+num2;
    }
    
},MINUS(){
    @Override
    public double eval(double num1, double num2) {
        return num1-num2;
    }
    
},TIMES {
    @Override
    public double eval(double num1, double num2) {
        return num1*num2;
    }
},DIVIDE {
    @Override
    public double eval(double num1, double num2) {
        return num1/num2;
    }
};
    private Operation() {
    }
    public abstract double eval(double num1,double num2);
    
    public static void main(String[] args) {
        System.out.println(Operation.PLUS.eval(5,3));
        System.out.println(Operation.MINUS.eval(5, 3));
        System.out.println(Operation.TIMES.eval(5,3));
        System.out.println(Operation.DIVIDE.eval(5,3));
    }
    
}

 

以上是关于枚举类的主要内容,如果未能解决你的问题,请参考以下文章

同名的类函数宏和枚举器

带有红宝石集合/可枚举的酷技巧和富有表现力的片段[关闭]

JAVA枚举小结

如何通过单击片段内的线性布局从片段类开始新活动?下面是我的代码,但这不起作用

php 枚举类代替hard code代码

php 枚举类代替hard code代码