黑马程序员_高新技术之枚举

------- android培训java培训、期待与您交流! ----------

枚举:

枚举让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。

枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。

枚举类只有几种特定的值,并且会在编译期间就检查,避免非法值。

比如:对于星期天的值,不同的人理解不是同的,可能在赋值的过程中赋了不同的值,而编译器只检查语法而无法提示出来,那么等程序运行的时候就可以出现错误!

所以,枚举就出现了。它实现了让某个类型的变量的取值只能是若干个固定值中的一个,否则在编译期间编译器就会报错,提高了程序运行的安全性。

参考:EnumTest.java,WeekDay.java

使用普通的java类来实现枚举类,可以帮助理解:

1.私有化构造方法并定义两个或多个全局对象;

即:private WeekDay(){}

public final static WeekDay SUN = new WeekDay();

public final static WeekDay SAT = new WeekDay();

再调用该类的对象时,只能是WeekDay weekDay = WeekDay.SUN;

此时常量SUNSAT其实就是WeekDay的一个对象。

public WeekDay nextDay(){

if(this == SUN){

return MON;

}else{

return SUN;

}

}

public String toString(){

return this == SUN?"SUN":"MON";

}

我们可以将nextDay()方法抽象化,让子类来复写。

---------------------------------------------------------------------

public abstract WeekDay nextDay();----

public final static WeekDay SUN = new WeekDay(){

public WeekDay nextDay(){

return MON;

}

}

注意:此时每一个枚举常量其实就是该类的匿名内部类对象了。

使用普通类来模拟一个枚举类,总结:

第一步:私有的构造方法

第二步:每个元素分别用一个公有的静态成员变量表示

第三步:可以有若干公有方法或抽象方法。该例子:采用抽象方法定义nextDay就将大量的if.else语句转移成了一个个独立匿名内部类。

即:在模拟的内部类中定义几个匿名内部类。

在枚举内中定义几个抽象方法,由子类实现

public final static WeekDay SUN = new WeekDay(){子类的实现方式};

public final static WeekDay SAT= new WeekDay(){子类的实现的方式};

所以枚举中的成员常量实际上是该枚举类的匿名内部类对象。

---------------------------------------------------------------------------

思考:如何定义一个枚举类呢?

main(){

WeekDay weekDay2 = WeekDay.FRI;

System.out.println(weekDay2);

System.out.println(weekDay2.name());//

System.out.println(weekDay2.ordinal());

System.out.println(WeekDay.valueOf("SUN")); //返回带指定名称的指定枚举类型的枚举常量。

System.out.println(WeekDay.values().length); //吧所有的元素转换成数组,以便操作

}

public enum WeekDay(){

SUN,MON,TUE,WED,THI,FRI,SAT

}

-------------------------------------------------------

思考2:实现带有构造方法的枚举

注意: 1.构造方法必须位于元素列表之后。

2.构造方法必须私有化;

3.还可以定义带参数的构造方法;

4.当类中存在多个构造方法时,

在枚举中定义构造方法,必须被私有化并定义在常量后面。

成员常量可以通过传递数字来指定调用那个构造方法。

public enum WeekDay{

SUN,MON,TUE,WED,THI,FRI,SAT;

private WeekDay(){System.out.println("first");}//空参数的构造方法

private WeekDay(int day){System.out.println("second");}//带参数的构造方法

只要用到该类的静态成员,那么静态成员初始化时会默认调用构造方法。

如果在获取枚举常量时,要指定调用哪个构造方法,可以在静态常量后面+(实际参数或者不加实际参数),比如:SUN(1),MON()默认会调用有参数的构造方法;

}

----------------------------------------------------------------------------------------------------------------------------------

思考3:实现带有抽象方法的枚举(做一个交通灯)

public enum TrafficLamp{

RED(30){

public TrafficLamp nextLamp(){ //子类复写

return GREEN;

}

},

GREEN(45){

public TrafficLamp nextLamp(){

return YELLOW;

}

},

YELLOW(5){

public TrafficLamp(){

return RED;

}

};

public abstract TrafficLamp nextLamp();//父类的抽象方法

private int time;//时间属性

private TrafficLamp(int time){

this.time = time;

}

}

public enum TrafficLamp{

RED(30)/*小括号内有无参数可以指定构造方法*/{子类复写抽象方法

},

GREEN(45){子类复写抽象方法

},

YELLOW(5){子类复写抽象方法

};

public abstract TrafficLamp nextLamp();//注意返回的仍然是枚举类对象!绝!

private int time;

private TrafficLamp(int time){this.time = time}

注意:普通类的对象在创建时,可以调用该类的有参数的构造方法,如new Date(300){};

}

注意:RED(30)/*小括号内有无参数可以指定构造方法*/{子类复写抽象方法

},表示:用静态全局常量RED引用该类的实体对象,该对象通过调用父类的有参的构造方法。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值