小白学JAVA之十——枚举
一. 枚举的定义
- 使用public static final表示的常量描述较为繁琐,使用enum关键字来定义枚举类型取代常量,枚举类型是从Java5开始增加的一种引用数据类型。
- 枚举值就是当前类的类型,也就是指向本类的对象,默认使用public static final关键字共同修饰,因此采用枚举类型.的方式调用。
- 枚举类可以自定义构造方法,但是构造方法的修饰符必须是private,默认也是私有的。
二. 案例分析
编程实现所有方向的枚举,所有的方向:向上、向下、向左、向右。
1.引出枚举
在没有枚举之前,我们会通过自定义一个含有string类型成员变量的类来表示Direction,通过new对象给string赋值“向上”“向下”“向左”“向右”来表示方向。
public static void main(String[] args) {
// 1.声明Direction类型的引用指向该类型的对象并打印特征
Direction d1 = new Direction("向上");
System.out.println("获取到的字符串是:" + d1.getDesc()); // 向上
Direction d2 = new Direction("向下");
System.out.println("获取到的字符串是:" + d2.getDesc()); // 向下
Direction d3 = new Direction("向左");
System.out.println("获取到的字符串是:" + d3.getDesc()); // 向左
Direction d4 = new Direction("向右");
System.out.println("获取到的字符串是:" + d4.getDesc()); // 向右
System.out.println("-------------------------------------");
Direction d5 = new Direction("向前");
System.out.println("获取到的字符串是:" + d5.getDesc()); // 向前
}
}
但这样会出现一个问题,即如上代码块中的对象d5所示,明明我们不需要Direction类有向前的方向,却依旧能够成功创建。因此,我们需要用到枚举,只给它限定静态的四个方向对象供程序员使用。
2. 使用方式
1.1 定义Direction类
将需要枚举的对象以静态常量的形式出现。
- 代码如下:
/**
* 编程实现所有方向的枚举,所有的方向:向上、向下、向左、向右
*/
public class Direction {
private final String desc; // 用于描述方向字符串的成员变量
// 2.声明本类类型的引用指向本类类型的对象
public static final Direction UP = new Direction("向上");
public static final Direction DOWN = new Direction("向下");
public static final Direction LEFT = new Direction("向左");
public static final Direction RIGHT = new Direction("向右");
// 通过构造方法实现成员变量的初始化,更加灵活
// 1.私有化构造方法,此时该构造方法只能在本类的内部使用
private Direction(String desc) {
this.desc = desc;
}
// 通过公有的get方法可以在本类的外部访问该类成员变量的数值
public String getDesc() {
return desc;
}
}
1.2 调用
打印方向信息有两种方法:
- 调用对象的get方法打印方向字符串
- 直接根据枚举类型分类打印
两种情况代码如下:
public class DirectionUseTest {
// 自定义静态方法实现根据参数指定的字符串内容来打印具体的方向信息
public static void test1(String str) {
switch (str) {
case "向上":
System.out.println("抬头望明月!"); break;
case "向下":
System.out.println("低头思故乡!"); break;
case "向左":
System.out.println("左牵黄"); break;
case "向右":
System.out.println("右擎苍"); break;
default:
System.out.println("没有这样的方向哦!");
}
}
// 自定义静态方法实现根据参数指定的枚举类型来打印具体的方向信息
public static void test2(DirectionEnum de) {
switch (de) {
case UP:
System.out.println("抬头望明月!"); break;
case DOWN:
System.out.println("低头思故乡!"); break;
case LEFT:
System.out.println("左牵黄"); break;
case RIGHT:
System.out.println("右擎苍"); break;
default:
System.out.println("没有这样的方法哦!");
}
}
public static void main(String[] args) {
DirectionUseTest.test1(Direction.UP.getDesc());
DirectionUseTest.test1("今天是个好日子!");
System.out.println("--------------------------------------------");
DirectionUseTest.test2(DirectionEnum.DOWN);
//DirectionUseTest.test2("今天是个好日子!"); Error:类型不匹配,减少了出错的可能性
}
}
三. 枚举类的常用方法
所有的枚举类都继承自java.lang.Enum类,常用方法如下:
public class DirectionEnumTest {
public static void main(String[] args) {
// 1.获取DirectionEnum类型中所有的枚举对象
DirectionEnum[] arr = DirectionEnum.values();
// 2.打印每个枚举对象在枚举类型中的名称和索引位置
for (int i = 0; i < arr.length; i++) {
System.out.println("获取到的枚举对象名称是:" + arr[i].toString());
System.out.println("获取到的枚举对象对应的索引位置是:" + arr[i].ordinal()); // 和数组一样下标从0开始
}
System.out.println("---------------------------------------------------------------");
// 3.根据参数指定的字符串得到枚举类型的对象,也就是将字符串转换为对象
//DirectionEnum de = DirectionEnum.valueOf("向下"); // 编译ok,运行发生IllegalArgumentException非法参数异常
DirectionEnum de = DirectionEnum.valueOf("DOWN");
//DirectionEnum de = DirectionEnum.valueOf("UP LEFT"); // 要求字符串名称必须在枚举对象中存在
//System.out.println("转换出来的枚举对象名称是:" + de.toString());
System.out.println("转换出来的枚举对象名称是:" + de); // 当打印引用变量时,会自动调用toString方法
System.out.println("---------------------------------------------------------------");
// 4.使用获取到的枚举对象与枚举类中已有的对象比较先后顺序
for(int i = 0; i < arr.length; i++) {
// 当调用对象在参数对象之后时,获取到的比较结果为 正数
// 当调用对象在参数对象相同位置时,则获取到的比较结果为 零
// 当调用对象在参数对象之前时,则获取到的比较结果为 负数
System.out.println("调用对象与数组中对象比较的先后顺序结果是:" + de.compareTo(arr[i]));
}
System.out.println("---------------------------------------------------------------");
// 5.使用数组中每个DirectionEnum对象都去调用show方法测试
for (int i = 0; i < arr.length; i++) {
arr[i].show();
}
}
}
四. 枚举类实现接口的方式
枚举类实现接口后需要重写抽象方法,而重写方法的方式有两种:重写一个,或者每个对象都重写。