enum不能继承其他类,有时我们需要扩展原enum中的元素,有时我们希望使用子类将一个enum中的元素进行分组。在一个接口的内部,创建实现该接口的枚举,以此将元素进行分组,可以达到将枚举元素分类组织的目的。举例来说,假设你想用enum来表示不同类别的食物,同时还希望每个enum元素仍然保持Food类型。那么可以这样实现:
package com.zy.test;
import com.zy.test.Food.Appetizer;
import com.zy.test.Food.MainCourse;
interface Food {
enum Appetizer implements Food {
SALAD, SOUP, SPRING_ROLLS;
}
enum MainCourse implements Food {
LASAGNE, BURRITO, PAD_THAI,
LENTILS, HUMMOUS, VINDALOO;
}
enum Dessert implements Food {
TIRAMISU, GELATO, BLACK_FOREST_CAKE,
FRUIT, CREME_CARAMEL;
}
}
public class InterfaceOrganizeEnum {
public static void main(String[] args) {
Food food = Appetizer.SALAD;
food = MainCourse.LASAGNE;
}
}
对于enum而言,实现接口是使其子类化的唯一办法,所以嵌入在Food中的每个enum都实现了Food接口。现在,在main方法中,可以使用实现了Food接口的enum类型,那么我们就可以将其实例向上转型为Food,所以上例中的所有东西都是Food。
当需要与一大堆类型打交道时,接口就不如enum好用了。例如,如果你想创建一个“枚举的枚举”,那么可以创建一个新的enum,然后用其实例包装Food中的每一个enum类:
package com.zy.test;
import java.util.Random;
import com.zy.test.Food.Appetizer;
import com.zy.test.Food.MainCourse;
interface Food {
enum Appetizer implements Food {
SALAD, SOUP, SPRING_ROLLS;
}
enum MainCourse implements Food {
LASAGNE, BURRITO, PAD_THAI,
LENTILS, HUMMOUS, VINDALOO;
}
enum Dessert implements Food {
TIRAMISU, GELATO, BLACK_FOREST_CAKE,
FRUIT, CREME_CARAMEL;
}
}
public class InterfaceOrganizeEnum {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
for (Course course : Course.values()) {//先获取枚举
Food f = course.randSelection();//获取枚举的枚举,这也是一种管理枚举的方式
System.out.println(f);
}
}
}
}
enum Course {
APPETIZER(Food.Appetizer.class),
MAINCOURSE(Food.MainCourse.class);
private Food[] values;
private Course(Class<? extends Food> kind) {
values = kind.getEnumConstants();// 返回此枚举类的元素
}
public Food randSelection() {
Random random = new Random(47);
return values[random.nextInt(values.length)];
}
}
在这个例子中,我们通过遍历每一个Course实例来获得“枚举的枚举”的值。下面我们还将看到另一种枚举实例的方式。此外,还有一种更简洁的管理枚举的办法,就是将一个enum嵌套在另一个enum内,就像以下代码:
package com.zy.test;
import java.util.Random;
import com.zy.test.Food.Appetizer;
import com.zy.test.Food.MainCourse;
import com.zy.test.SecurityCategory.Security;
public class InterfaceOrganizeEnum {
public static void main(String[] args) {
Random random = new Random(47);
SecurityCategory[] valueTemp = SecurityCategory.class.getEnumConstants();
for (int i = 0; i < 10; i++) {
SecurityCategory category = valueTemp[random.nextInt(valueTemp.length)];
System.out.println(category + ":" + category.randomSelection());
}
}
}
enum SecurityCategory {
STOCK(Security.Stock.class), BOND(Security.Bond.class);
Security[] values;
SecurityCategory(Class<? extends Security> kind) {
values = kind.getEnumConstants();
}
interface Security {
enum Stock implements Security { SHORT, LONG, MARGIN}
enum Bond implements Security {MUNICIPAL, JUNK}
}
public Security randomSelection() {
Random random = new Random(50);
return values[random.nextInt(values.length)];
}
}
输出结果:
BOND:JUNK
STOCK:LONG
BOND:JUNK
STOCK:LONG
STOCK:LONG
BOND:JUNK
STOCK:LONG
STOCK:LONG
BOND:JUNK
BOND:JUNK
解析:Security接口的作用是将其所包含的enum组合成一个公共类型,这一点是很有必要的,然后,SecurityCategory才能将Security中的enum作为其构造器的参数使用,以便起到组织的效果。
以上就是这一节的内容,原本看书<java 编程思想>看不懂这么做的原因,第二变才看懂,本节的重点在于当枚举嵌套,枚举类型比较多时怎么使用各种方式将其整齐规范的组织起来。