枚举类概述:
特点: 类的对象只有有限个,个数是确定的
当需要定义一组常量时(常量之间是有关系的,都描述的是一个东西,比如季节)(常量意味着不能修改,所以不能对对象进行重新赋值,只能拿来用),建议使用枚举类,枚举类中放的是对象,对象是常量
定义枚举类的两种方式:
方式一: JDK5.0以前,自定义枚举类,该类是继承于Object的
方式二: JDK5.0可以使用enum关键字来定义枚举类,该类继承于Enum类
注意:如果枚举类中只有一个对象,则可以作为单例模式的实现方式
方式一:自定义枚举类
package test01;
public class Test{
public static void main(String[] args) {
//用常量给变量进行赋值
Season spring=Season.SPRING;
System.out.println(spring);//Season [seasonName=春天, seasonDesc=春暖花开]
}
}
//自定义枚举类Season
class Season{
//注意用final修饰的属性不能采用默认初始化,要手动赋值,否则报错。
//如果直接显式赋值或者用代码块赋值会使得对象的属性都一样,所以用构造器进行赋值
//1.声明Season对象的属性:用private final修饰
private final String seasonName;
private final String seasonDesc;//季节描述
//2.私有化类的构造器,就不能在类的外面去new对象了,并给对象属性赋值
private Season(String seasonName,String seasonDesc) {
this.seasonName=seasonName;
this.seasonDesc=seasonDesc;
}
//3.提供当前枚举类的多个对象:用public static final,因为是public,所以外面可以直接获取类的对象
//对象是常量,用final修饰
public static final Season SPRING=new Season("春天","春暖花开");
public static final Season SUMMER=new Season("夏天","夏日炎炎");
public static final Season FALL=new Season("秋天","秋高气爽");
public static final Season WINTER=new Season("冬天","冰天雪地");
//4.其他诉求:比如获取枚举类对象的属性,提供get方法,因为属性是final,所以获取不能使用set方法更改属性值
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
//4.其他诉求:提供toString方法
@Override
public String toString() {
return "Season [seasonName=" + seasonName + ", seasonDesc=" + seasonDesc + "]";
}
}
方式二:使用关键字enum定义枚举类
这种方式就不用写public static final了,不是说像接口中那样可写可不写,是一定不要写,否则报错
且因为对象的类型相同,所以把类型也删掉,而且要把= new 类型名也删掉
用enum定义上来先不要写属性和方法,先把对象放上去,即先提供对象,否则报错
多个对象之间用逗号隔开,不要用分号,最后一个对象的末尾用分号
package test01;
public class Test{
public static void main(String[] args) {
Season summer=Season.SUMMER;
System.out.println(summer);//SUMMER,这里调用的toString方法(被重写过)并没有输出地址值,而是输出常量名,说明enum的直接父类不是Object
System.out.println(Season.class.getSuperclass());//class java.lang.Enum,所以直接父类为Enum
}
}
enum Season{
//3.提供当前枚举类的对象,对象作为常量出现,多个对象之间用逗号隔开,末尾对象用分号结束
SPRING("春天","春暖花开"),
SUMMER("夏天","夏日炎炎"),
FALL("秋天","秋高气爽"),
WINTER("冬天","冰天雪地");
//1.声明Season对象的属性:用private final修饰
private final String seasonName;
private final String seasonDesc;//季节描述
//2.私有化类的构造器,这样就不能在类的外面去new对象了,并给对象属性赋值
private Season(String seasonName,String seasonDesc) {
this.seasonName=seasonName;
this.seasonDesc=seasonDesc;
}
//4.其他诉求:比如获取枚举类对象的属性,提供get方法,因为属性是final,所以不能使用set方法更改属性值
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
//一般情况下就不去重写toString了,enum的父类Enum已经进行了重写,如果有别的诉求,比如不想打印名字,也可以进行重写
//4.其他诉求:提供toString方法
//@Override
//public String toString() {
//return "Season [seasonName=" + seasonName + ", seasonDesc=" + seasonDesc + "]";
//}
}
Enum类的主要方法
1)values()方法:返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值
2)valueOf(String str):可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如果不是,会有运行时异常: IllegalArgumentException
3) toString():返回当前枚举类对象常量的名称
package test01;
public class Test{
public static void main(String[] args) {
Season[] seasons=Season.values();//元素是我们定义的对象常量
for(int i=0;i<seasons.length;i++) {
System.out.println(seasons[i]);
}
//例如看线程的状态:
Thread.State[] states=Thread.State.values();
for(int i=0;i<states.length;i++) {
System.out.println(states[i]);
}
//valueOf(String objName);//返回枚举类中对象名是objName的对象,如果没有,则抛异常IllegalArgumentException
Season winter1=Season.valueOf("WINTER");//比如我们想根据WINTER这个名字去找到所对应的对象
System.out.println(winter1);//WINTER
Season winter2=Season.valueOf("WINTER1");//报异常IllegalArgumentException
}
}
enum Season{
//3.提供当前枚举类的对象,对象作为常量出现,多个对象之间用逗号隔开,末尾对象用分号结束
SPRING("春天","春暖花开"),//如果枚举类对象没有属性,那就直接写SPRING即可
SUMMER("夏天","夏日炎炎"),
FALL("秋天","秋高气爽"),
WINTER("冬天","冰天雪地");
//1.声明Season对象的属性:用private final修饰
private final String seasonName;
private final String seasonDesc;//季节描述
//2.私有化类的构造器,就不能在类的外面去new对象了,并给对象属性赋值
private Season(String seasonName,String seasonDesc) {
this.seasonName=seasonName;
this.seasonDesc=seasonDesc;
}
//4.其他诉求:比如获取枚举类对象的属性,提供get方法,因为属性是final,所以获取对象后不能使用set方法更改属性值
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
}
枚举类实现接口
情况一:在enum类中实现抽象方法
对于自定义的枚举类(即没有用enum关键字)来说,实现接口就和普通的类实现接口没什么区别
让使用enum关键字定义的枚举类实现接口,也是implements接口就行
package test01;
public class Test{
public static void main(String[] args) {
Season winter1=Season.valueOf("WINTER");
System.out.println(winter1);//WINTER
winter1.show();//这是一个季节
}
}
interface info{
void show();
}
enum Season implements info{
//3.提供当前枚举类的对象,对象作为常量,出现多个对象之间用逗号隔开,末尾对象用分号结束
SPRING("春天","春暖花开"),//如果枚举类对象没有属性,那就直接写SPRING即可
SUMMER("夏天","夏日炎炎"),
FALL("秋天","秋高气爽"),
WINTER("冬天","冰天雪地");
//1.声明Season对象的属性:用private final修饰
private final String seasonName;
private final String seasonDesc;//季节描述
//2.私有化类的构造器,就不能在类的外面去new对象了,并给对象属性赋值
private Season(String seasonName,String seasonDesc) {
this.seasonName=seasonName;
this.seasonDesc=seasonDesc;
}
//4.其他诉求:比如获取枚举类对象的属性,提供get方法,因为属性是final,所以不能使用set方法更改属性值
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
@Override
public void show() {
System.out.println("这是一个季节");
}
}
情况二:让枚举类的对象分别实现接口中的抽象方法
因为上面程序中的show方法,用任何一个枚举类的对象去调用,输出都是一样的,我们希望每一个对象调用show方法时得到不同的结果,可以让每一个对象去重写抽象方法,可以写针对于对象的具体操作
package test01;
public class Test{
public static void main(String[] args) {
Season winter1=Season.valueOf("WINTER");
System.out.println(winter1);//WINTER
//Season winter2=Season.valueOf("WINTER1");//报异常IllegalArgumentException
winter1.show();//大约在冬季
}
}
interface info{
void show();
}
enum Season implements info{
//3.提供当前枚举类的对象,对象作为常量,出现多个对象之间用逗号隔开,末尾对象用分号结束
SPRING("春天","春暖花开"){
@Override
public void show() {
System.out.println("春天在哪里");
}
},
SUMMER("夏天","夏日炎炎"){
@Override
public void show() {
System.out.println("宁静的夏天");
}
},
FALL("秋天","秋高气爽"){
@Override
public void show() {
System.out.println("落叶堆积了好几层");
}
},
WINTER("冬天","冰天雪地"){
@Override
public void show() {
System.out.println("大约在冬季");
}
};
//1.声明Season对象的属性:用private final修饰
private final String seasonName;
private final String seasonDesc;//季节描述
//2.私有化类的构造器,就不能在类的外面去new对象了,并给对象属性赋值
private Season(String seasonName,String seasonDesc) {
this.seasonName=seasonName;
this.seasonDesc=seasonDesc;
}
//4.其他诉求:比如获取枚举类对象的属性,提供get方法,因为属性是final,所以获取对象后不能使用set方法更改属性值
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
// @Override
// public void show() {
//
// System.out.println("这是一个季节");
// }
}