-------------------------------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
什么是枚举:
在JDK中是1.5的新特性,是一个叫ENUM的类,是Java枚举类型的公共基本类。
枚举目的就是要让某个变量的取值只能为若干固定值中的一个,否则,编译就会报错。
另外,注意,枚举中,如果只有一个成员,就可以作为一个单例的实现方式。
枚举的好处:
枚举可以让编译器在编译时就可以控制源程序中填写的非法值,
普通变量的方式在开发阶段无法实现这一目标。
枚举的常用方法:
values,valueOf,name,toString,ordinal.
重要方法:这里是将外部的字符串变成了WeekDay的一个对象,
打印的时候调用了WeekDay的toString方法,默认存在可以不写。
System.out.println(WeekDay.valueOf("SUN").toString());
System.out.println(WeekDay.values().length);
这样要注意,length不是方法,而是属性,所以没有括号
for (WeekDay string : WeekDay.values()) { //这里是对枚举进行遍历
System.out.println(string);
}
总结: 枚举是一种特殊的类,其中的每一个元素都是该类的一个实例对象。
例如可以调用WeekDay.SUN.getClass().getName()
用普通类如何来实现枚举功能?下面定义一个Weekday(工作日)的类来模拟枚举功能。
import java.util.Iterator;
import java.util.Date;
// 在WeekDay中,可以通过大量的IF else语句完成,也可以通过抽象方法中的内部内分别完成。
//这里是对枚举的模拟。
public class EnumTest {
public enum WeekDay{
//这里,枚举是一个类,所以可以有构造方法。
SUN(1),MON,TUE,WED,THI,FRI,SAT;
//这里的每一个都可以看做是一个对象存在。等效于静态成员对象。
private WeekDay(){System.out.println("first");}
//构造方法必须私有,只要用到了枚举类,静态变量都会被初始化。
private WeekDay(int day){System.out.println("second");}
}
public static void main(String[] args) {
//下面这句要给weekDay变量赋值,只给给出WeekDay类中定义好的常量,不能再定义其外的值。这就是枚举。
WeekDay1 weekDay = WeekDay1.MON;
// 下面这个对象调用WeekDay中的方法。
System.out.println(weekDay.nextDay());
//枚举示例:
WeekDay weekDay2 = WeekDay.FRI;
System.out.println(weekDay2);//这里会打印出 FRI,表示枚举自己提供了toString方法。
System.out.println(weekDay2.name()); //打印名字结果同上。
System.out.println(weekDay2.ordinal()); //得到枚举在序列中的位置。
/* System.out.println(weekDay2.getClass()); //得到枚举类。
System.out.println(weekDay2.getDeclaringClass());//返回本类的申明处。一个类可能是在另一个类内部定义的.
*/
new Date(30){};// 这里的Date(300)可以看成是父类Date的带参构造。
}
枚举的细节:
枚举的所有元素对象,应该位于枚举类中所有成员位置的顶端,它们之间逗号隔开。但是整体必须以分号结尾。
枚举的构造:枚举构造必须私有,枚举的宗旨是提供若干的元素对象,并限定使用者只能在枚举提供的范围内进行选择。
如果构造不私有而能够被外部调用,那么枚举的对象限定的目的就会被破坏。
跟单例的思想有共通的地方,不同的是可以有更多的元素对象存在。
如果定义元素的获取?
枚举中所有的元素都是对象,在运行的时候他们会进行构造。
我们可以通过构造来增加一些功能,例如或许通过一个元素对象,获取下一个。
在枚举元素的后面增加一对括号,我们可以选择性传入参数,从而限定它执行那一个构造方法。
例如在枚举后面加空括号,默认会执行无参构造。
在枚举后括号内添加类型参数,就可以指定它去找局部那个参数的构造方法进行实例化。
(老师的实例中回顾:外部类之能有2个修饰符,一个是默认的,一个是public。而内部内是可以进行那四种访问修饰的。)
package 枚举学习;
//这里转出创建一个WeekDay类。 用于模拟枚举的实现。
public abstract class WeekDay1 {
private WeekDay1(){} //首先私有化构造方法,这样限定之后,其他人无法再创建。
//下面这句话是常量,创建星期日的对象,是枚举中限定值的部分,可以列举一个星期的7个值。
public final static WeekDay1 SUN = new WeekDay1(){
//这里真的内部类的对象作为SUN,求下一个日期。所以。生成方法中的下一个返回值就是MON。
public WeekDay1 nextDay() {
return MON;
}
}; //大括号表示定义了WeekDay的子类,是一个内部类。这里子类要赋给父类的方法。
public final static WeekDay1 MON = new WeekDay1(){
public WeekDay1 nextDay() {
return SUN;
}
};
public abstract WeekDay1 nextDay();
//枚举中可以定义方法吗? 求出下个星期值。
/*public WeekDay nextDay(){ //这个方法不能为静态,因为上面有了实实在在的对象。所以不适用静态。
if(this == SUN){
return MON; //由于是WeekDay类型,所以需要返回值。
}else {
return SUN;
}
} */
//有没有第二种办法实现nextDay方法呢;用抽象方法,这个时候。类也变成了抽象类。
public String toString(){ //这里要输出结果,结果是String类型,所以返回值是String。
return this==SUN?"SUN":"MON";
}
}
重点概念:枚举中,元素是枚举类的一个对象,而当元素进行构造的时候,它相当于是枚举类的一个匿名子类。
这个时候就应用到了枚举类中抽象方法的重写。
在成员位置定义一个抽象方法,在枚举元素后的括号中可以进行抽象方法的重写。
public enum Trafficlamp{
RED(30){ //这里可以看做是一个子类,并调用构造方法
public Trafficlamp nextlamp(){ //在这里,trafficlamp就是一个类,三个灯是它的实例化子类。
return GREED;
}
},
GREED(45){
public Trafficlamp nextlamp(){
return YELLOW;
}
},
YELLOW(5){
public Trafficlamp nextlamp(){
return RED;
}
};
public abstract Trafficlamp nextlamp();
private int time;
private Trafficlamp(int time){
this.time=time;
}
}
-------------------------------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------