枚举类(Enumeration)
引入
设计季节类,按照过往的思路,每个季节都要创建新的对象来代表“春、夏、秋、冬”,但是一共就四个,且不用修改。因此可以设计枚举类,即把具体的对象一个一个例举出来。
介绍
- 枚举是一组常量的集合,简写为
enum
- 枚举属于特殊的类,里面只包含一组有限特定的对象。
枚举类的实现
自定义方式实现
- 不用提供set方法,因为枚举对象值通常只读
- 对枚举的对象/属性要用
final
和static
共同修饰,实现底层优化 - 枚举对象名通常使用全部大写,即常量的命名规范
- 枚举对象根据需要可以有多个属性。
//enumeration01.java
public class enumeration01 {
public static void main(String[] args) {
System.out.println(Season.SPRING);
}
}
class Season{
//1. 将构造器私有化,防止直接被new出来
//2. 去掉类内对外的set方法,防止属性被修改,可以保留get方法
//3. 在Season类内部直接创建固定对象
//4. 加 final优化,final和 static一起用则不会加载类
private String name;
private String desc;//描述
//此处直接在本类中创建一组对象
public static final Season SPRING = new Season("春天","温暖");
public static final Season SUMMER = new Season("夏天","炎热");
public static final Season AUTUMN = new Season("秋天","凉爽");
public static final Season WINTER = new Season("冬天","寒冷");
private Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
@Override
public String toString() {
return "Season{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
输出结果:
Season{name='春天', desc='温暖'}
enum 关键字实现
-
使用enum关键字开发一个枚举类时,默认会继承Enum类
-
使用简化语法时,必须明确调佣的是哪个构造器
-
使用无参构造器创建枚举对象时,实参列表 和 小括号 都可以省略
//enumeration02.java
public class enumeration02 {
public static void main(String[] args) {
System.out.println(Season02.SPRING);
}
}
//使用enum实现
enum Season02{
/** 步骤
* 1. 使用关键字enum 代替 class
* 2. 用 常量名(实参列表) 代替创建对象的语法
* SPRING("春天","温暖"); 本质上等价于 public static final Season SPRING = new Season("春天","温暖");
* 3. 有多个常量,使用 , 号分隔
* 4. enum类中,定义常量的语句写在最前面
*/
SPRING("春天","温暖"),SUMMER("夏天","炎热"),AUTUMN("秋天","凉爽"),WINTER("冬天","寒冷");
private String name;
private String desc;//描述
private Season02(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
@Override
public String toString() {
return "Season{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
练习
- 下面的代码是否正确?并说明含义.
enum Gender{
BOY,GIRL;
}
-
语法正确,上面是一个枚举类Gender
-
该枚举类没有属性,也只有默认无参构造器,因此常量名后面不需要括号
- 下面的代码输出什么?
enum Gender2{
BOY,GIRL;
}
Gender2 boy = Gender2.BOY;
Gender2 boy2 = Gender2.BOY;
System.out.println(boy);
System.out.println(boy == boy2);
//enumExercise01.java
public class enumExercise01 {
public static void main(String[] args) {
Gender2 boy = Gender2.BOY;
Gender2 boy2 = Gender2.BOY;
System.out.println(boy);//输出boy所在类的toString方法,没有就用父类Enum的toString方法。
/**
Enum类的toString 底层实现如下, name为类名
public String toString(){
return name;
}
*/
System.out.println(boy == boy2);//本质上是同一个枚举对象
}
}
enum Gender2{
BOY,GIRL;
}
输出结果:
BOY
true
枚举对象的常用方法
toString
:Enum
已经重写过,返回当前对象名。子类可以重写用于返回对象的属性信息。name
:返回当前对象名,子类中不能重写。ordinal
:返回当前对象的位置号,默认从0开始values
: 返回当前枚举类中的所有常量valueOf
: 将字符串转换成枚举对象,要求字符串必须为已有的常量名否则报错。compareTo
: 比较两个枚举常量,比较的就是位置号
//EnumMethod.java
public class EnumMethod {
public static void main(String[] args) {
//使用enumExercise02.java中的Season02枚举类作为常用方法的演示
// SPRING("春天","温暖"),SUMMER("夏天","炎热"),
// AUTUMN("秋天","凉爽"),WINTER("冬天","寒冷");
Season02 autumn = Season02.AUTUMN;
//name()输出枚举对象的名字
System.out.println(autumn.name());
//ordinal()输出该枚举对象的次序/编号(从0开始),AUTUMN为第 2 个
System.out.println(autumn.ordinal());
//values() 返回Season02[],包含了定义的所有枚举对象
Season02[] values = Season02.values();
for(Season02 season : values) {//增强 for 循环,按顺序输出values中的每一个season
System.out.println(season);
}
//valueOf() 根据输入的值去枚举类中去查找,如果找到了就返回,没找到就报错
Season02 autumn1 = Season02.valueOf("AUTUMN");
System.out.println("autumn1:" + autumn1);
//compareTo 比较枚举编号的大小,返回的结果为差值 ,下面的SUMMER 编号1,AUTUMN编号2, 1-2=-1
System.out.println(Season02.SUMMER.compareTo(Season02.AUTUMN));
}
}
注意事项
使用enum
后:
- 不能再继承其他类,因为
java
是单继承,而使用enum
关键字会默认继承了Enum
类 - 可以实现接口。如下:
enum 类名 implements 接口1, 接口2{}