目录
(四)面向对象:
12、枚举类:
(1)概述:
(2)枚举类的定义格式:
(3)编译与反编译:
(4)Enum类的特点:
(5)枚举类的测试类以及一些特有的方法:
(四)面向对象:
12、枚举类:
(1)概述:
为什么要有枚举类:
1、类型安全,String类的color传入“1”也不会报错,但其实无意义;而enum是强类型,只能使用预定义的值。
2、语意清晰,代码可读性高
3、限定取值范围,避免非法值。
定义:是一种特殊得类,通过enum关键字定义。
(2)枚举类的定义格式:
枚举元素必须写在第一行,如果有多个的话,用逗号','隔开,最后用分号';'结束 ,如果';'后面没有其他内容的话,';'可以省略,但不建议省略
枚举元素和枚举元素()效果一样,含义为:执行枚举类默认构造器去实例化枚举元素对象
Gender g1 = Gender.Male; //Male() : Male = new Gender();
枚举元素本质上是枚举类对象,由static与final修饰。
[修饰符] 数据类型 数据成员名;
[修饰符] 数据类型 数据成员方法(){……}
枚举类可以由普通数据成员(方法与属性)
private 构造方法();
private 构造方法(参数){……}
构造方法必须私有化
不自定义是,系统提供无参构造
枚举元素那里如果调用,必须定义
[修饰符] static 返回值 成员方法名(){……}
[修饰符] static 返回值 成员属性名;
枚举类中可以由静态方法与属性
}
以上是没有抽象方法的枚举类的定义格式,从上也可以看出,枚举类中可以由普通成员,构造方法,静态成员。
下面我们展示案例:
//枚举类基本定义
enum Week {//枚举元素必须写在第一行,如果有多个的话,用逗号','隔开,//最后用分号';'结束//如果';'后面没有其他内容的话,';'可以省略,但不建议省略MON, TUE, WED; //WED()//WED和WED()效果一样,含义为:执行枚举类默认构造器去实例化枚举元素对象//源代码类似:public static final Week WED = new Week();//注意:用户没有提供构造器,系统会提供默认的构造器 private Week(){}//枚举类数据成员和成员方法,可以包含一个或多个private String desc;public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}//枚举类构造方法,如果不提供,系统会提供默认构造方法,private修饰//如果用户自定义枚举类构造方法,则系统不再提供private Week2() {}//自定义枚举方法,注意必须用private修饰private Week2(String desc) {this.desc = desc;}
}
接下来是含有抽象方法的枚举类的定义:
[修饰符] enum 枚举类名{
枚举元素1(根据构造方法传实参){
重写该类所有的抽象方法;
},枚举元素2(根据构造方法传实参){
重写该类所有的抽象方法;
},……枚举元素n(根据构造方法传实参){
重写该类所有的抽象方法;
};
理解:当我们定义了一个抽象方法,一般是有子类继承后重写,然后利用多态调用,但是我们的enum类是final修饰的类,无法被子类继承,那如何来重写抽象方法,这里我们想到了匿名内部类,我们可以在创建对象时通过匿名内部类来重写抽象方法,那我们又想到了枚举类的特殊性,创建的对象只能取预定义好的枚举元素那不能再创建对象时写匿名内部类,我们就只能在枚举类中创建枚举元素时,为枚举元素写匿名内部类。(枚举类可以理解为在类内部预定义对象,类外创建的对象只能等于这些预定义对象,那可以理解为实际上枚举元素就是对象。)
抽象方法不能私有,且每个枚举元素都必须重写所有的抽象方法。
抽象方法声明;
}
案例展示:
enum Week3 {//注意:包含抽象方法的枚举类是抽象类,不能直接实例化对象//所以定义枚举类元素(所有)时候,一定要重写抽象方法//注意:必须在所有的枚举元素定义中,重写所有抽象方法//MON {MON() {//在枚举元素中重写抽象方法@Overridepublic void show() {System.out.println("in show, MON: 周一");}}, TUE("星期二") {//注意,每个枚举元素中都要重写重写方法,且要重写所有的抽象方法@Overridepublic void show() {System.out.println("in show, TUE: " +this.getDesc());}};//枚举类数据成员及get方法private String desc;public String getDesc() {return desc;}//枚举类自定义构造方法private Week3() {}private Week3(String desc) {this.desc = desc;} //枚举类 包含的 抽象方法(可以0或多个)public abstract void show();
}
(3)编译与反编译:
我们编写的enum类是不完整的,有很代码或者修饰符都被省略掉了
我们可以通过反编译去查看源码:
javap enum类的字节码文件
但是这样获得的源码是隐藏了私有属性与方法的,如果想查看,则需要使用命令
javap -p enum类的字节码文件
从这里我们也可以看出来:
枚举类Gender本质上是一个final修饰的类,不可以被继承
枚举类会默认继承 java.lang.Enum 这个抽象泛型类
枚举元素,本质上是枚举类对象,且由 static和final 修饰
枚举类提供私有构造器,我们在类外不能主动创建枚举类对象
枚举类中可以包含 public static 静态方法
注意:包含抽象方法的enum类,不会被final修饰
(4)Enum类的特点:
<1>类由final修饰,不能被继承,但是final会隐身,反编译即可看到,包含抽象方法的enum类,不会被final修饰。
<2>枚举元素由final与static修饰,唯一且不能被修改,由类名直接调用
<3>枚举类设有非私有构造器,外界不能通过new创建对象
<4>可以包含静态方法
(5)枚举类的测试类以及一些特有的方法:
<1>对象的赋值只能是枚举元素:Gender g1 = Gender.MALE;
<2>输出枚举对象,默认输出枚举元素
<3>获取枚举元素名字的方法:g.name();
<4>获取枚举元素编号:g.ordinal();(返回int型);