一、枚举类简介
java 5新增了一个关键“enum",enum与class、interface等关键字的地位相同,他表示一种新的自定义数据类型——枚举类型。我们知道java中所有的类都有一个共同的基类java.lang.Object,但是被定义成枚举类的类并不继承java.lang.Object,而是继承了java.lang.Enum类,java开发文档中明确指出java.lang.Enum”这是所有java枚举类型的的公共基本类型“。
枚举类型作为一种特殊的自定义数据类型,他和普通类一样可以有自己的field、方法、构造函数,也可以实现一个或多个接口,但作为特殊的自定义数据类型,枚举类型有自己的特点。
1. 枚举类的构造函数只能是private修饰;
2. 使用关键字enum定义的枚举类型默认不再继承java.lang.Object,而是默认继承java.lang.Enum;
3. 使用enum关键字定义枚举类型默认是final修饰,因此枚举类型不能派生子类;
4. enum关键字定义的枚举类的所有实例只能也必须在第一行显示列出,否则这个枚举类型永远也不能产生实例(后面详解),列出的实例系统会默认加上public static final修饰;
5. 枚举类再定义的时候就要列出其所有的实例,例如季节的所有实例是春夏秋冬,性别的所有实例是男性、女性;
6. 所有的枚举都有一个values方法(这个方法不在java.lang.Enum类中),可以方便的遍历枚举实例;
二、枚举类深入
-
手动实现枚举类
手动实现枚举类,首先需要私有化构造器,接着把这个类所有可能的实例都是用public static final修饰并初始化,最后如有必要,可以定义一些对外的方法允许其他类根据特定的参数来获取与之匹配的实例。
模拟实现季节枚举,其总共有四个实例SPRINT,SUMMER,FAIL,WINTER,示例代码如下。
package oop;
public class SeasonEnumDemo {
private String name;
/*
* 私有构造方法
*/
private SeasonEnumDemo(String name){
this.name = name;
}
/*
* 实例化该枚举类所有的实例
*/
public static final SeasonEnumDemo SPRING =
new SeasonEnumDemo("春天");
public static final SeasonEnumDemo SUMMER =
new SeasonEnumDemo("夏天");
public static final SeasonEnumDemo FAIL =
new SeasonEnumDemo("秋天");
public static final SeasonEnumDemo WINTER =
new SeasonEnumDemo("冬天");
/*
* 也可以对外提供获取实例的方法
*/
public static SeasonEnumDemo getIntertance(String name){
switch (name) {
case "春天":
return SPRING;
case "夏天":
return SUMMER;
case "秋天":
return FAIL;
case "冬天":
return WINTER;
default:
return null;
}
}
}
-
如何使用枚举类
使用enum关键字实现一个最简单的季节枚举类型的定义,代码示例如下。
package oop;
public enum SeasonEnumSimple {
/*
* 必须在第一行列出该枚举所有的实例,一下代码形如:
* public static final SeasonEnumSimple SPRINT = new SeasonEnumSimple();
* public static final SeasonEnumSimple SUMMER = new SeasonEnumSimple();
* public static final SeasonEnumSimple FAIL = new SeasonEnumSimple();
* public static final SeasonEnumSimple WINTER = new SeasonEnumSimple();
*/
SPRINT, SUMMER, FAIL, WINTER
}
那么如何使用关键字enum定义一个枚举类来表示以上自定义的季节枚举,示例代码如下。
package oop;
public enum SeasonEnum {
/*
* 必须在定义枚举类的第一行列出其所有实例,这些实例默认会使用public static final修饰
* 例如:public static final SeasonEnum SPRINT = new SeasonEnum("春天");
*/
SPRING("春天"), SUMMER("夏天"), FAIL("秋天"), WINTER("冬天");
private String name;
/*
* 私有化构造方法
*/
private SeasonEnum(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
既然有了枚举类,那么当然要使用以下,查看java.lang.Enum类的方法,其中需要关注compareTo、name、ordinal、toString、valueOf、values,使用实例如下。
package oop;
public class Main {
public static void main(String[] args) {
/*
* values方法遍历举例
* 输出:SPRING SUMMER FAIL WINTER
*/
/*
* toString方法举例
* 另外,在打印se的时候,默认调用了Enum类的toString方法,这个方法打印的是在申明枚举所有实例的时候定义的名字
* 这个名字通过name方法也可以获取,不过应该优先使用toString方法
*/
for(SeasonEnum se : SeasonEnum.values())
System.out.print(se + " ");
/*
* name方法举例
* 通过name方法获取实例名字,这个名字是在Enum类中定义,其值为声明枚举实例的时候的实例名字
* 例如本例中打印SPRINT,因为在声明实例的时候声明的名字为SPRINT("春天"),因此这个实例的枚举名为SPRINT
* 输出:SPRING
*/
System.out.println(SeasonEnum.SPRING.name());
/*
* ordinal方法举例:
* 枚举实例定义的时候,会按照顺序赋予一个ordinal序号,这个序号从0开始,按照枚举实例的顺序递增
* 输出:0 1 2 3
*/
for(SeasonEnum se : SeasonEnum.values())
System.out.print(se.ordinal() + " ");
/*
* compareTo方法举例
* 因为java.lang.Enum类实现了Comparable接口,因此重写了compareTo方法
* 这个方法会根据每个枚举实例的ordinal序号来做比较,声明序号越靠后的越大
* 输出:-3
*/
System.out.println(SeasonEnum.SPRING.compareTo(SeasonEnum.WINTER));
}
}
-
深入了解枚举类
1. 实现接口的枚举类
枚举类实现了接口,则在枚举类中必须重写接口定义的抽象方法,这一点和普通类一样,但是这样会有一个问题,也就是所有的枚举实例对象都具有相同的方法,但实际上不同的枚举实例会自定义该方法,如以下示例,顶一个计算接口,接口中有compute方法(如果定义成加减两个方法则会导致冗余),这个方法希望枚举中的”加“实例能做加法,希望”减“实例能做减法,示例代码如下。
package demo;
/*
* 计算接口:希望不同功能的枚举实例重写这个方法之后能够实现不同的操作
*/
public interface ComputeInterface {
public abstract int compute();
}
实现的方式很多,以下示例是一般实现方式(枚举有自己特定的实现方式),代码示例如下。
package demo;
/*
* 实现的方式很多
*/
public enum ComputeEnum implements ComputeInterface {
Addition,SUBTRACTION,MULTIPLICATION,DIVISION;
@Override
public int compute(int num1, int num2) {
// TODO Auto-generated method stub
switch (this) {
case Addition:
return num1+num2;
case SUBTRACTION:
return num1-num2;
case MULTIPLICATION:
return num1*num2;
case DIVISION:
return num1/num2;
default:
return 0;
}
}
}
枚举特定的实现方式,在申明每个枚举实例对象的时候,自定义该方法,代码示例如下。package demo;
/*
* 枚举特定的实现方式,另种方式哪一种更好,仁者见仁,总有用得上的场景
*/
public enum ComputeEnumSpecial implements ComputeInterface {
Addition{
@Override
public int compute(int num1, int num2) {
// TODO Auto-generated method stub
return num1+num2;
}
},
SUBTRACTION{
@Override
public int compute(int num1, int num2) {
// TODO Auto-generated method stub
return num1-num2;
}
},
MULTIPLICATION{
@Override
public int compute(int num1, int num2) {
// TODO Auto-generated method stub
return num1*num2;
}
},
DIVISION{
@Override
public int compute(int num1, int num2) {
// TODO Auto-generated method stub
return num1/num2;
}
};
}
调用代码示例如下。
package demo;
public class Main {
public static void main(String[] args) {
System.out.println(ComputeEnum.Addition.compute(2, 3));
System.out.println(ComputeEnum.MULTIPLICATION.compute(2, 3));
System.out.println(ComputeEnum.DIVISION.compute(2, 3));
System.out.println(ComputeEnum.SUBTRACTION.compute(2, 3));
System.out.println(ComputeEnumSpecial.Addition.compute(2, 3));
System.out.println(ComputeEnumSpecial.MULTIPLICATION.compute(2, 3));
System.out.println(ComputeEnumSpecial.DIVISION.compute(2, 3));
System.out.println(ComputeEnumSpecial.SUBTRACTION.compute(2, 3));
}
}
2. 包含抽象方法的内部类
枚举类不能派生子类,那么包含了抽象方法的枚举类如何实现重写抽象方法?借鉴上面实现接口的枚举类中枚举类特定的实现方式,示例代码如下。
package demo;
/*
* 包含抽象方法的枚举类举例
*/
public enum EnumIncludeAbstractFunction {
Addition{
@Override
public int compute(int num1, int num2) {
// TODO Auto-generated method stub
return num1+num2;
}
},
SUBTRACTION{
@Override
public int compute(int num1, int num2) {
// TODO Auto-generated method stub
return num1-num2;
}
},
MULTIPLICATION{
@Override
public int compute(int num1, int num2) {
// TODO Auto-generated method stub
return num1*num2;
}
},
DIVISION{
@Override
public int compute(int num1, int num2) {
// TODO Auto-generated method stub
return num1/num2;
}
};
/*
* 枚举类包含的抽象方法
*/
public abstract int compute(int num1, int num2);
}
附注:
本文如有错漏之处,烦请不吝指正,谢谢!
188

被折叠的 条评论
为什么被折叠?



