8. 枚举 enum
8.1 枚举的定义和用处
定义:枚举也是一种自定义的静态的引用数据类型,遵循大驼峰命名法(不推荐使用Unicode字符,例’男’),这种类型与类相似,但多了一种成员:枚举元素,用于限定某些变量的取值范围。
使用场合:当某些变量的取值范围仅在有限的几个值中选择,则可以将这些变量设为枚举类型(枚举是可以实现接口的)。
使用优势:可以大幅度提高代码的可读性。
8.2 枚举的声明与使用
声明关键字:enum
在枚举中需写全改枚举类型变量的每一个值,这些值称为枚举元素。
例:
//描述性别的枚举
public enum Gender {
Male,Female
}
public class Program1 {
public static void main(String[] args) {
//1.声明一个枚举类型的变量
Gender gender;
//给变量赋值
gender = Gender.Male;
Month month = Month.Feb;
}
}
enum Month{
Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
}
8.3 【拓展】枚举中其他的定义
枚举中,除了可以定义枚举的元素之外,还可以定义属性、⽅法、构造⽅法。但是,这些部分必须写
在枚举的元素之后,且所有的枚举元素定义结束之后需要加⼀个分号。
枚举中还可以对Object类中的⽅法进⾏重写,因此,枚举可以认为是Object类的⼀个最终⼦类。不
能再被继承了。
8.3.1 枚举类型详解
枚举类型,在编译之后,也会生成.class字节码文件。枚举,可以认为是Object的一个特殊的子类,并且不能被继承。实际上,枚举的父类是 Enum,所有自定义的枚举类型,都是继承自Enum类,而Enum类的父类是Object。
1. 枚举对象,是可以向上转型为Object类型的
2. 枚举可以继承到Object类中的一些方法
3. 在枚举中,可以重写Object类中的一些方法
8.3.2 枚举中的成员定义
枚举中,其实也可以和类一样,定义属性、方法、构造方法,但是前提条件是: 上方所有的枚举值最后需要添加一个分号。
8.3.3 枚举中的构造方法
枚举中是可以定义构造方法的,但是这里的构造方法,和类中的构造有区别。
- 枚举中的构造方法,默认的访问权限是 private
- 可以为枚举写构造方法的重载
- 枚举值,即是一个枚举静态对象,在声明的时候,其实是自动调用构造方法实例化的
public enum Gender {
// 这里的每一个值,其实都是当前枚举的一个静态属性
// 这里,会通过当前枚举的构造方法进行实例化
Male("男"), Female("女"), Unknown("未知");
private String desc; // 对每一个属性值的描述
Gender(String desc) {
this.desc = desc;
System.out.println("一个枚举对象被实例化了");
}
@Override
public String toString() {
return this.desc;
}
}
8.3.4 枚举值
枚举值,其实是一个枚举的静态的对象。在枚举被加载到内存的时候,其实是自动调用构造方法实例化的。
8.3.5 枚举实现接口
与类相同,枚举也可以实现接口,且可以实现多个接口。只需要保证,在枚举中将实现的所有的接口中的所有抽象方法都重写实现即可。
public enum Gender implements GenderComparable {
@Override
public int compareToOther(Gender other) {
return 0;
}
}
8.3.6 枚举的内部匿名子类(难)
在枚举中定义的每一个值,在后面添加大括号,可以形成当前枚举的匿名子类。在匿名子类中,可以对枚举中的方法进行重写。
public enum Season {
Spring {
// 这里,其实就类似于是一个Season的匿名子类
@Override
public void showDesc() {
System.out.println("春天来了,万物复苏。");
}
// 这个方法,可以写,但是外部是无法调用的
public void show() {
System.out.println("Spring Show");
}
},
Summer, Autumn, Winter;
/**
* 枚举中定义的方法,用来输出每一个季节的描述
*/
public void showDesc() {
System.out.println("这是一个适合学习的季节");
}
}
注:因为枚举是静态的,一般不适用于类中,作为属性等。