您的位置:首页 > 职场人生

黑马程序员-java枚举总结

2014-07-07 17:16 267 查看
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------

一、为什么要有枚举

先看一个问题:当要定义表示一个星期几的变量时,该如何定义?假设有人用1-7分别表示周一至周日,但也有人可能用0表示周日。

枚举的出现是为了让某个类型的变量的取值只能为若干个固定值中的一个,否则编译器就会报错。枚举可以让编译器在编译时期就发现源程序中填写的非法值,而普通变量在开发阶段无法实现这个目标。

首先,我们先试着用普通类模拟枚举,这样便于后面我们对枚举的理解

二、用普通类模拟枚举的实现原理

1)私有的构造方法;2)每个元素分别用一个公有的静态成员变量表示;3)可以有若干个公有方法或抽象方法。

例1:

package com.cn.itcast;

public abstract class WeekDay1 {
//构造方法私有,从而从外部新建WeekDay1对象
private WeekDay1(){}
/**************************************************************************************
//定义7个表示星期的常量,且是WeekDay1类型
public final static WeekDay SUN=new WeekDay();
public final static WeekDay MON=new WeekDay();
public final static WeekDay TUE=new WeekDay();
public final static WeekDay WEN=new WeekDay();
public final static WeekDay THU=new WeekDay();
public final static WeekDay FRI=new WeekDay();
public final static WeekDay SAT=new WeekDay();

//定义返回第二天的方法,利用if...else判断,麻烦
public WeekDay nextDay(){
if(this==SUN)
return MON;
else if(this==MON)
return TUE;
else if(this==TUE)
return WEN;
else if(this==WEN)
return THU;
else if(this==THU)
return FRI;
else if(this==FRI)
return SAT;
else
return SUN;
}
//复写toString方法,利用if...else判断,麻烦
public String toString(){
if(this==SUN)
return "SUN";
else if(this==MON)
return "MON";
else if(this==TUE)
return "TUE";
else if(this==WEN)
return "WEN";
else if(this==THU)
return "THU";
else if(this==FRI)
return "FRI";
else
return "SAT";
}*****************************************************************************************/
//利用if...else判断,麻烦。直接在定义每个对象时,利用匿名内部类复写nextDay()、toString()方法
public final static WeekDay1 SUN=new WeekDay1(){
public WeekDay1 nextDay(){
return MON;
}
public String toString(){
return "SUN";
}
};
public final static WeekDay1 MON=new WeekDay1(){
public WeekDay1 nextDay(){
return TUE;
}
public String toString(){
return "MON";
}
};
public final static WeekDay1 TUE=new WeekDay1(){
public WeekDay1 nextDay(){
return WEN;
}
public String toString(){
return "TUE";
}
};
public final static WeekDay1 WEN=new WeekDay1(){
public WeekDay1 nextDay(){
return THU;
}
public String toString(){
return "WEN";
}
};
public final static WeekDay1 THU=new WeekDay1(){
public WeekDay1 nextDay(){
return FRI;
}
public String toString(){
return "THU";
}
};
public final static WeekDay1 FRI=new WeekDay1(){
public WeekDay1 nextDay(){
return SAT;
}
public String toString(){
return "FRI";
}
};
public final static WeekDay1 SAT=new WeekDay1(){
public WeekDay1 nextDay(){
return SUN;
}
public String toString(){
return "SAT";
}
};

//定义两个抽象方法
public abstract WeekDay1 nextDay();
public abstract String toString();

}


package com.cn.itcast;

public class EnumTest {

public static void main(String[] args) {
WeekDay1 weekDay1=WeekDay1.MON;
System.out.println(weekDay1);
System.out.println(weekDay1.nextDay());
}
}
输出结果:

MON
TUE

三、枚举的基本应用

例2:

class EnumTest {
public static void main(String[] args) {
WeekDay weekDay=WeekDay.SUN;
System.out.println(weekDay);
System.out.println(weekDay.name());
System.out.println(weekDay.ordinal());//返回该元素在元素列表中的位置
System.out.println(WeekDay.valueOf("SUN"));//将字符串转为WeekDay类型,WEB开发中常用
System.out.println(WeekDay.values().length);//返回包含枚举内所有元素的数组,从而可以用数组思想操作它们
}
//定义一个表示星期的枚举
public enum WeekDay{
SUN,MON,TUE,WEN,THU,FRI,SAT;
}
}
输出结果:

SUN
SUN
0
SUN
7
总结:枚举是一种特殊的类,其中的每个元素都是该类的一个实例对象。如可以这样调用:WeekDay.SUN.getClass().getName()等。枚举类也有许多方法:如values()、valueOf()、name()、toString()、ordinal()等。

接下来,我们再深入了解一下枚举。

四、实现带有构造方法的枚举

例3:

class EnumTest {
public static void main(String[] args) {
WeekDay weekDay=WeekDay.SUN;
System.out.println(weekDay);
System.out.println(weekDay.name());
System.out.println(weekDay.ordinal());
System.out.println(WeekDay.valueOf("SUN"));
System.out.println(WeekDay.values().length);
}
//定义一个带有构造方法的枚举
public enum WeekDay{
//调用哪个构造函数,由元素后面的括号传入的参数个数与类型决定
//不带括号的默认调用无参构造函数,也可以加对空括号,同样表示调用无参构造函数
SUN(1),MON(),TUE(1),WEN,THU,FRI,SAT;//元素列表必须位于最前面。若后面还有代码,则分号结尾。
//构造函数必须私有
private WeekDay(){System.out.println("first");}
private WeekDay(int day){System.out.println(day+"second");}
}
}
输出结果:

1second
first
1second
first
first
first
first
SUN SUN 0 SUN 7

五、实现带有抽象方法的枚举

例4:

package com.cn.itcast;

public class EnumTest {

public static void main(String[] args) {
TrafficLamp tl=TrafficLamp.GREEN;
System.out.println(tl);
System.out.println(tl.time);
System.out.println(tl.nextLamp());
}
public enum TrafficLamp{
//以匿名内部类的形式,复写父类TrafficLamp的抽象方法nextLamp()
RED(40){
@Override
public TrafficLamp nextLamp(){
return GREEN;
}
},
GREEN(30){
@Override
public TrafficLamp nextLamp() {
return YELLOW;
}
},
YELLOW(10){
@Override
public TrafficLamp nextLamp() {
return  RED;
}
};
//定义一个抽象方法
public abstract TrafficLamp nextLamp();
//定义一个成员变量,表示时间
private int time;
//通过构造函数给time赋值
private TrafficLamp(int time){this.time=time;}
}
}


输出结果:

GREEN
30
YELLOW


我们去翻看EnumTest.java编译得到的class文件,如图所示,



不仅有EnumTest.class以及代表内部类的EnumTest$TrafficLamp.class,还有三个匿名内部类:EnumTest$TrafficLamp$1、EnumTest$TrafficLamp$2、EnumTest$TrafficLamp$3。这三个类正表示了定义RED、GREEN、YELLOW时所产生的匿名内部类。

总结:

1)枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法;

2)枚举元素必须位于枚举体中的最开始部分,枚举元素列表的后面要用分号与其他成员分隔。若将其他成员置于枚举元素列表前面,编译器会报错;

3)带构造方法的枚举:

①构造方法必须私有;

②如果有多个构造方法,则由枚举元素后面括号内的参数列表决定调用的构造方法;

③枚举元素MON与MON()都是调用默认的无参构造方法。

4)带抽象方法的枚举:每个元素分别是由枚举类的匿名子类生成的实例对象。这些子类通过类似匿名内部类的方式进行定义,并复写父类枚举类的抽象方法。

5)枚举只有一个成员时,可以作为一种单例模式的实现方式。

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 枚举