JAVA枚举类型

来源:互联网 发布:周末网络国债理财机构 编辑:程序博客网 时间:2024/06/05 11:50

一、引言

在进行系统开发时,我们常会用数字或者字母去存储一些枚举项。比如用M表示男、F表示女,或者用1表示经理、2表示前台、3表示收银台、4表示厨房等等。但是如果在代码中出现:

if(type == "1"){  ......}else if(type == "2"){  ...}....
类似上述的代码,对于新员工或者系统维护人员来说,是一件非常头疼的事情。代码可读性非常低,而且很容易出错。

在JAVA SE5以下,JAVA语言并没有提供枚举类型,当时sun公司进行设计时,许多地方借鉴了C/C++语言,但是也取消了C/C++中部分数据类型,譬如枚举类型、结构体等。sun公司认为用普通类就可以完成枚举类型的功能。但是随着信息系统的日益壮大,sun公司又重新开始考虑枚举类型的必要性了。那么,我们先来利用普通类去实现枚举类型,体验一下枚举类型为我们带来的好处。

二、普通类实现枚举类型

假设我们要用MON、SUN表示周一和周日(周二~周六做法雷同),我们希望用Week.MON和Week.SUN进行调用。代码如下:

public class MyWeekEnum {        private MyWeekEnum() { //防止new对象,即用户只能得到指定的类型        }        //实现用户只能得到MON和SUN        public static MyWeekEnum MON = new MyWeekEnum();        public static MyWeekEnum SUN = new MyWeekEnum();}

public static void main(String[] args) {MyWeekEnum week = MyWeekEnum.MON;if (week == MyWeekEnum.SUN) {System.out.println("sun");} else if (week == MyWeekEnum.MON) {System.out.println("mon");} //输出为:mon}
这样,一个最简单的枚举就写完了。接下来,我们考虑枚举类型是不是可以和其他普通类一样,有自己的方法。比如说我想知道明天是周几,即我想添加一个getNextDay()这样一个方法。我们可以这样实现:

public class MyWeekEnum {private MyWeekEnum() { // 防止new对象,即用户只能得到指定的类型}// 实现用户只能得到MON和SUNpublic static MyWeekEnum MON = new MyWeekEnum();public static MyWeekEnum SUN = new MyWeekEnum();public MyWeekEnum getNextDay() {if (this == MON) {return SUN;} else {return MON;}}}
public static void main(String[] args) {MyWeekEnum week = MyWeekEnum.MON;System.out.println(week.getNextDay() == MyWeekEnum.MON); //faliseSystem.out.println(week.getNextDay() == MyWeekEnum.SUN); //true}

到目前为止,我们确实实现了枚举类型以及为枚举类型添加方法。但是由于枚举类型大家的地位是一样的,大家可能都希望能够自己去实现具体的方法,只希望MyWeekEnum能够提供一个"接口"告诉我需要实现哪些方法。而且如果用上述的方法去实现,一旦枚举类型的量大了,需要书写一大堆if...else,容易出错。于是我们进行了如下重构:

public abstract class MyWeekEnum {        private MyWeekEnum() { // 防止new对象,即用户只能得到指定的类型}// 实现用户只能得到MON和SUNpublic static MyWeekEnum MON = new MyWeekEnum() {@Overridepublic MyWeekEnum getNextDay() { //具体实现return SUN;}};public static MyWeekEnum SUN = new MyWeekEnum() {@Overridepublic MyWeekEnum getNextDay() { //具体实现return MON;}};public abstract MyWeekEnum getNextDay(); //抽象方法}
这里需要注意的是MyWeekEnum需要定义成抽象类。MON和SUN变成了MyWeekEnum的子类,并重写父类方法,有点小多态的味道。最后,我们尝试一下在枚举类型里面添加常量。代码如下:

public abstract class MyWeekEnum {private MyWeekEnum() { // 防止new对象,即用户只能得到指定的类型}private MyWeekEnum(String describe) {this.describe = describe;}// 实现用户只能得到MON和SUNpublic static MyWeekEnum MON = new MyWeekEnum("周一") {@Overridepublic MyWeekEnum getNextDay() {return SUN;}};public static MyWeekEnum SUN = new MyWeekEnum("周日") {@Overridepublic MyWeekEnum getNextDay() {return MON;}};public abstract MyWeekEnum getNextDay();private String describe;public String getDescribe() {return this.describe;}}
public static void main(String[] args) {MyWeekEnum week = MyWeekEnum.MON;System.out.println(week.getDescribe()); //周一}
三、枚举类型使用
在第二小节中,我们实现了JAVA枚举类型大部分常见的功能。相信如果了解了第二小节的内容再看JAVA的枚举类型会轻松不少。首先,我们来看看JAVA的枚举类型是如何定义的:

public enum Week {MON,SUN;}
这样一个枚举就定义好了,调用方式:Week.SUN、Week.MON,是不是觉得非常方便呢?其实,我们在创建enum时,编译器会为你生成一个相关的类,这个类继承自java.lang.Enum(所以enum类型不能再继承其他类了,但是可以实现其他多个接口),它自带了一些方法,接下来我们去研究一下这些方法。

1、values()  它可以返回enum实例的数组,而且他们的下标就是我们声明的顺序。

2、name()  它返回enum实例声明时的名称。

for (Week w : Week.values()) {System.out.println(w.name());}//输出为:MON SUN

3、ordinal()  它返回一个int,是每一个enum实例在声明时的次序,从0开始编号。

4、getDeclaringClass()  它可以返回enum实例所属的enum类。

5、valueOf()  它会根据给定的名称返回相应的enum实例,多用于web开发中,我们接收web前端提交的字符串,去生成一个enum实例。

Week week = Week.valueOf("MON"); // 模拟从web前端取到MON字符串System.out.println(week.name() + " " + week.getDeclaringClass()); //MON class edu.fjnu.test.Week

接下来我们来看看在enum中添加方法。其实和我们上述的实现大同小异。

public enum Week {MON(){@Overridepublic Week getNextDay() {return SUN;}}, SUN(){@Overridepublic Week getNextDay() {return MON;}};public abstract Week getNextDay();}
最后我们来看看枚举类型如何实现带参构造函数:

public enum Week {MON("周一") {@Overridepublic Week getNextDay() {return SUN;}},SUN("周日") {@Overridepublic Week getNextDay() {return MON;}};private Week() {}private Week(String describe) {this.describe = describe;}public abstract Week getNextDay();private String describe;public String getDescribe() {return this.describe;}}
public static void main(String[] args) {Week week = Week.valueOf("MON"); // 模拟从web前端取到MON字符串System.out.println(week.name() + " " + week.getDescribe()); //MON 周一}
枚举类型基本的用法大致就介绍到这里,欢迎大家围观吐槽!

0 0
原创粉丝点击