枚举类
- 一、引入
- 二、介绍
- 三、实现方式
- 1、 自定义类实现枚举
- 小结
- 2、 enum关键字实现枚举
- 四、使用enum注意事项
- 五、练习
- 六、enum常用方法
- 七、练习
- 八、enum和接口
一、引入
要求创建季节(Season)对象,请设计并完成。
- 传统方法:
public class Enumeration01 {
public static void main(String[] args) {
Season spring = new Season("春天", "温暖的");
Season summer = new Season("夏天", "炎热的");
Season autumn = new Season("秋天", "凉爽的");
Season winter = new Season("冬天", "寒冷的");
}
}
class Season {
private String name;
private String desc;//描述
public Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() { return name;}
public void setName(String name) { this.name = name;}
public String getDesc() { return desc;}
public void setDesc(String desc) { this.desc = desc;}
}
创建Season对象有如下特点
① 季节的值是有限的几个值(spring, summer, autumn, winter)。
② 只读,不需要修改。
按这个思路设计这种类,不能体现季节是固定的四个对象。
二、介绍
- 枚举对应英文(enumeration,简写enum)
- 枚举是一组常量的集合。
- 可以这里理解:枚举属于一种特殊的类,里面只包含一组有限的特定的对象。
三、实现方式
- 自定义类实现枚举
- 使用enum关键字实现枚举
1、 自定义类实现枚举
防止直接new => ① 构造器私有化
防止别人修改season的参数 => ② 去掉set相关方法
保持Season固定四个 => ③ 在Season内部,直接创建固定的对象
让别人直接用固定的对象 => ④ static
public class Enumeration02 {
public static void main(String[] args) {
System.out.println(Season.SPRING);
System.out.println(Season.SUMMER);
System.out.println(Season.AUTUMN);
System.out.println(Season.WINTER);
}
}
class Season {
private String name;
private String desc;//描述
public static Season SPRING = new Season("春天", "温暖的");
public static Season SUMMER = new Season("夏天", "炎热的");
public static Season AUTUMN = new Season("秋天", "凉爽的");
public static 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 + '\'' +
'}';
}
}
小结
- 分析
- 不需要提供setXxx方法,因为枚举对象值通常为只读。
- 对枚举对象/属性使用final + static共同修饰,实现底层优化。
加final不会导致static类的加载,不是说new不会加载。 - 枚举对象名通常使用全部大写,常量的命名规范。
- 枚举对象根据需要,也可以有多个属性。Enumeration02.java
- 方法总结
- 构造器私有化
- 本类内部创建一组对象四个春夏秋冬]
- 对外暴露对象(通过为对象添加 public final static修饰符)
- 可以提供get方法,但是不要提供set
2、 enum关键字实现枚举
如果使用了enum来实现枚举类
① 使用关键字enum替代 class
② public static final Season SPRING = new Season(“春天”,“温暖")直接使用 SPRING(“春天”,“温暖") 代替
解读:常量名(实参列表) : 实参列表和构造器参数列表相同
③ 如果有多个常量对象,使用《逗号》间隔即可
④ 如果使用enum 来实现枚举,要求将定义的常量对象,写在前面
//① 使用关键字enum替代 class
enum Season2 {
// ② 常量名(实参列表)
// ④ 如果使用enum 来实现枚举,要求将定义的常量对象,写在前面
SPRING("春天", "温暖"), //③ 如果有多个常量对象,使用《逗号》间隔即可
SUMMER("夏天", "炎热"),
AUTUMN("秋天", "凉爽"),
WINTER("冬天", "寒冷");
private String name;
private String desc;//描述
private Season2(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注意事项
- 当我们使用enum关键字开发一个枚举类时,默认会继承Enum类,而且是一个final类。
[证明] 使用 javap 证明 【见下文 案例 a】
《hello.java》文件 通过 [ javac ] 指令进行编译,编译为《hello.class》
反编译使用 [ javap ] - 传统的 public static final Season2 SPRING = new Season2(“春天”,“温暖“);简化成SPRING(“春天”“温暖”),这里必须知道,它调用的是哪个构造器。
- 如果使用无参构造器创建枚举对象,则实参列表和小括号都可以省略。【见下文 案例 b】
- 当有多个枚举对象时,使用逗号间隔,最后有一个分号结尾
- 枚举对象必须放在枚举类的行首
【 案例 a 】
【 案例 b 】
第三行的 WHAT()是使用了无参构造器,也可以去掉小括号。
enum Season2 {
SPRING("春天", "温暖"), SUMMER("夏天", "炎热"),
AUTUMN("秋天", "凉爽"),WINTER("冬天", "寒冷"), WHAT();
private String name;
private String desc;//描述
private Season2(String name, String desc) {
this.name = name;
this.desc = desc;
}
private Season2() {
//无参构造器
}
}
五、练习
- 题1 是否正确
enum Gender{
BOY,GIRL;
}
答案:
- 上面语法正确
- 枚举类Gender,没有属性,可以去掉小括号。
- 有两个枚举对象 BOY, GIRL使用的无参构造器创建。
- 此时的无参构造器是存在的
如果是下面这种写法,无参构造器被覆盖,就是错的。
enum Gender{ //错
BOY,GIRL;
private Gender(String name) {}
}
- 题2 输出
enum Gender2{
BOY,GIRL;
}
Gender2 boy = Gender2.BOY; (1)
Gender2 boy2 = Gender2.BOY; (2)
System.out.println(boy); (3)
System.out.println(boy2 == boy); (4)
答案:
(1) 正确
(2) 正确
(3) 本质是调用 Gender2 的 父类的 toString。
Gender2 是enum类,是Enum类的子类。
输出:BOY
(4) TRUE。因为对象是静态的,public static final。
六、enum常用方法
【跳转】enum常用方法
七、练习
public class EnumExercise01 {
public static void main(String[] args) {
Week[] values = Week.values();
System.out.println("=="+"所有星期的信息如下"+"==");
for (Week v : values) {
System.out.println(v.getCname());
}
}
}
enum Week {
MONDAY("星期一"),
TUESDAY("星期二"),
WEDNESDAY("星期三"),
THURSDAY("星期四"),
FRIDAY("星期五"),
SATURDAY("星期六"),
SUNDAY("星期日");
private String cname;//chinese name
private Week(String cname) {
this.cname = cname;
}
public String getCname() {
return cname;
}
}
注意这里可以改写 toString方法,然后在 main 方法的 for 循环中直接 println(v)
八、enum和接口
- 使用enum关键字后,就不能再继承其它类了,因为enum会隐式继承Enum,而Java是单继承机制。
- 枚举类和普通类一样,可以实现接口,如下形式。
enum 类名 implements 接口1,接口2 {
}
interface IPlaying {
public void playing();
}
enum Music implements IPlaying {
CLASSIC_MUSIC;
@Override
public void playing() {
System.out.println("播放好听的音乐");
}
}
本笔记是对韩顺平老师的Java课程做出的梳理。方便本人和观看者进行复习。
课程请见: https://www.bilibili.com/video/BV1fh411y7R8/?spm_id_from=333.999.0.0&vd_source=ceab44fb5c1365a19cb488ab650bab03