枚举类
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)); } }
以上是关于枚举类的主要内容,如果未能解决你的问题,请参考以下文章