枚举类是一种特殊的类,它可以有自己的成员变量、方法。可以实现一个或者多个接口,也可以定义自己的构造器。一个java源文件中,最多只能定义一个public访问权限的枚举类,且该java源文件也必须和该枚举类名相同。
但是枚举类终究不是普通的类,它和普通的类有以下区别:
- 枚举类可以实现一个或者多个接口,使用enum定义的枚举类默认继承了Java.lang.Enum类,而不是默认继承的Object类,因此枚举类不能显示继承其他父类。其中Java.lang.Enum 类实现了java.lang.Serializable和java.lang.Compareble两个接口。
- 使用enum定义。非抽象的枚举类默认会使用final修饰。因此枚举类不能派生子类。
- 枚举类的构造器只能使用private访问修饰符。
- 枚举类的所有实例必须在枚举类的第一行显示列出,否者这个枚举类永远不会产生实例。列出实例时,系统会自动添加 public static final 修饰,无需程序员显示添加。
枚举类默认提供了一个 values()方法,该方法可以很方便的遍历所有的枚举值。
由于所有的enum定义的枚举类默认继承了Java.lang.Enum类,Java.lang.Enum提供了以下几个方法:
- int compareTo(E e):该方法与指定的枚举对象比较顺序,同一个枚举实例与相同的枚举实例进行比较。如果该枚举对象位于指定枚举对象之前返回负整数,否者返回0.
- String name():返回次枚举实例的名称,这个名称就是定义枚举类列出的所有枚举值之一。
- int ordinal():返回枚举值在枚举类中的索引。
- String toString():返回枚举常量的名称。(与name(),返回的是同一值)
- public static<T extends Enum<T>> T valueOf(Class<T> enumType,String name):返回指定枚举中指定名称的枚举值。
枚举类实现接口,与普通的类是一样的,可实现一个或者多个接口。值得注意的是,如果由枚举类来实现接口的话,则每个枚举类调用该方法行为方式都是一样的。但是可以 让每个枚举类来实现该方法,从而实现了每个枚举值调用该方法表现不同。
package Enum;
public enum FruitEnum implements GenderDesc {
Apple("红色"){
public void info() {
System.out.println("我是苹果");
}
},
Orange("橘色"){
public void info() {
System.out.println("我是橘子");
}
},
Banana("黄色"){
// public void info() {
// System.out.println("我是香蕉");
// }
},
Pineapple("橙色"){
// public void info() {
// System.out.println("我是菠萝");
// }
};
private final String color;
private FruitEnum(String color) {
this.color = color;
}
public String getColoer() {
return color;
}
@Override
public void info() {
System.out.println("-------------------");
}
}
---------------------------------------我是分界线-----------------------------------
package Enum;
public class TestEnum {
public static void main(String[] args) {
for (FruitEnum e : FruitEnum.values()) {
System.out.println(e);
}
FruitEnum e = FruitEnum.Apple;
System.out.println(e.compareTo(FruitEnum.Orange));
System.out.println(e.compareTo(FruitEnum.Banana));
System.out.println(e.getColoer());
e.info();
FruitEnum.Banana.info();
FruitEnum.Pineapple.info();
}
}
输出:
Apple
Orange
Banana
Pineapple
-1
-2
红色
我是苹果
-------------------
-------------------
查看bin目录会发现,出现了FruitEnum$1.class,FruitEnum$2.class,FruitEnum$3.class,FruitEnum$4.class。其实这有点类似匿名内部类。枚举值后面紧跟了一堆花括号,花括号的部分实际上就是一个类体部分。在这种情况下,当创建Apple,Orange
枚举类的实例时,相当于创建了FruitEnum匿名子类的实例。但是前面提到过,枚举类不是被final修饰嘛,怎么还能派生子类呢?在bin目录下,查看FruitEnum.class,可以发现此时,FruitEnum已经被 abstract修饰了。这意味着并不是所有的枚举类被final修饰。对于一个枚举类而言,只要它包含了抽象方法,它就是抽象枚举类,系统会默认使用abstract修饰,而不是final。
包含抽样方法的枚举类:
package Enum;
public enum Operation {
ADD{
@Override
public double eval(double x, double y) {
return x + y;
}
},
MINUS{
@Override
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.ADD.eval(2, 3));
System.out.println(Operation.MINUS.eval(2, 3));
}
}