先看一个需求
要求创建季节(Season)对象,请设计并完成
public class enum1 {
public static void main(String[] args) {
Season spring = new Season("春天", "温暖");
Season summer = new Season("夏天", "炎热");
Season autumn = new Season("秋天", "凉爽");
Season winter = new Season("冬天", "寒冷");
//因为对于季节而言,他的对象是固定的四个,不会有别的
//按照这个设计思路,不能体现季节是固定的四个对象
Season other = 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;
}
@Override
public String toString() {
return "Season{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
枚举(即:把具体的对象一个个列举出来)
解决方案-枚举
枚举:是一组常量的集合
自定义类实现枚举:
- 不需要提供setxxx方法,因为枚举对象值通常为只读
- 对枚举对象/属性使用static final 修饰,实现底层优化
- 枚举对象名通常全部使用大写,常量的命名规范
- 枚举对象根据需要,可以有多个属性
public class enum2 {
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 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("冬天", "寒冷");
//1.将构造器私有化,目的:防止直接 new
//2.将set方法去掉,防止属性被修改。只能读,不能修改
//3.在Season内部,直接创建固定的对象,得使用public,别人得调用
//4.优化 可以加入final修饰符
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 + '\'' +
'}';
}
}
enum关键字实现枚举
- 使用关键字enum代替class
- public ...直接换为常量名(实参列表)
- 如果有多个常量,使用逗号,进行分割
- 如果使用enum来实现枚举,要求将定义常量对象写在最前面
public class enum3 { 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); } } enum Season{ //定义了四个对象,固定,不可增加 不可减少 不可改变 // 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("冬天", "寒冷"); SPRING("春天", "温暖"), SUMMER("夏天", "炎热"), AUTUMN("秋天", "凉爽"), WINTER("冬天", "寒冷"); private String name; private String desc; 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 + '\'' + '}'; } }
枚举对象必须放在枚举类的行首
如果我们使用的是无参构造器,创建常量对象,可以省略括号
课堂练习1:
下面代码是否正确,并说明表示的含义
enum Gender{
BOY,GIRL;
}
正确
枚举类Gender,没有属性
有两个枚举对象BOY,GIRL,调用Gender类的无参构造器
(如果有有参构造器,那就得把无参构造器写出来)
课堂练习2:
下面代码会输出什么?
public class enum4 {
public static void main(String[] args) {
Gender boy = Gender.BOY;
Gender boy2 = Gender.BOY;
System.out.println(boy);//通过源码知,return name 输出BOY
System.out.println(boy == boy2);//静态性质对象 同一个 true
}
}
enum Gender{
BOY,GIRL;
}
enum常用方法说明
使用关键字enum时,会隐式继承Enum类,这样我们就可以使用Enum类的相关方法
public class enum5 {
public static void main(String[] args) {
Season spring = Season.SPRING;
System.out.println(spring);
System.out.println("输出枚举常量对象的名称");
System.out.println(spring.name());
System.out.println("------------------------");
Season winter = Season.WINTER;
System.out.println("枚举对象的次序从0开始");
System.out.println(winter.ordinal());
System.out.println("------------------------");
System.out.println("遍历取出枚举对象");
Season[] values = Season.values();
for (Season season:values){
System.out.println(season);
}
System.out.println("------------------------");
Season spring1 = Season.valueOf("SPRING");
System.out.println(spring1);
System.out.println("-------------------------");
System.out.println("比较两个枚举常量位置号");
int i = spring.compareTo(winter);
System.out.println(i);
}
}
enum Season{
SPRING("春天", "温暖"),
SUMMER("夏天", "炎热"),
AUTUMN("秋天", "凉爽"),
WINTER("冬天", "寒冷");
private String name;
private String desc;
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='温暖'}
输出枚举常量对象的名称
SPRING
------------------------
枚举对象的次序从0开始
3
------------------------
遍历取出枚举对象
Season{name='春天', desc='温暖'}
Season{name='夏天', desc='炎热'}
Season{name='秋天', desc='凉爽'}
Season{name='冬天', desc='寒冷'}
------------------------
Season{name='春天', desc='温暖'}
-------------------------
比较两个枚举常量位置号
-3
.toString() 返回枚举常量的名字 return name
.name() 返回当前对象名
.ordinal() 返回当前对象的位置号
.values() 返回当前枚举类中所有的常量
.valueOf() 将字符串转换为枚举对象,要求字符串必须为已有的常量名,否则报异常
.compareTo() 比较两个枚举常量,比较的是位置号
课堂练习3:
声明Week枚举类,其中包含星期一到星期日的定义;
使用values返回所有的枚举数组,并遍历
public class enum6 {
public static void main(String[] args) {
Week[] values = Week.values();
System.out.println("==所有星期的信息如下==");
for(Week week:values){
System.out.println(week);
}
}
}
enum Week{
MONDAY("星期一"),TUESDAY("星期二"),
WEDNESDAY("星期三"),THURSDAY("星期四"),
FRIDAY("星期五"),SATURDAY("星期六"),SUNDAY("星期日");
private String name;
Week(String name) {
this.name = name;
}
//重写了toString方法
@Override
public String toString() {
return name;
}
}
==所有星期的信息如下==
星期一
星期二
星期三
星期四
星期五
星期六
星期日
使用enum关键字后,就不能继承其他类了,因为enum会隐式继承Enum,而Java是单继承机制
enum实现的枚举类,仍然是一个类,所以还是可以实现接口的