一.为什么要有枚举类
有些集合不能或很难用公式或者叙述定理、规则等界定并做到既无遗漏,又无多余。而其个数有相对较少(有限)。此时用“枚举”可以最简单的说明这个集合的全部元素组成。例如:在某人在超市购买的东西,显然,无法用任何公式或规则表达,最简单的办法就是“枚举”:逐一列出购买的东西。
枚举类其实就是用来代替常量的。
比如我现在有5个选项,篮球、足球、乒乓球、羽毛球、游泳。这5个选项我们可以使用常量进行定义起来。我们将这五种类型定义成是String类型的。让用户选择一种来进行设置他的爱好。但是可能会有这样的一种情况:用户并不用我们定义出来的常量,而是自己写了一堆乱七八糟的东西,但是类型还是String。由于语法上没有错误,因此我们也不能说他错了。
而如果我们用到了枚举类的话,就可以避免这个问题了。
我们的类型是枚举类的类型,用户只能使用我们定义枚举类的值,不能使用别的值了。
二.JDK1.5以前的枚举类
枚举类的步骤:
- 提供类的属性,修饰private final
- 声明为final的属性在构造器中初始化
- 通过公用方法调用属性
- 创建枚举类对象,用public static final修饰
//枚举类
class Season
{
//提供类的属性,修饰private final
private final String seasonName;
private final String seasonDes;
//声明为final的属性在构造器中初始化
public Season(String seasonName,String seasonDes) {
this.seasonName=seasonName;
this.seasonDes=seasonDes;
}
//通过公用方法调用属性
public String getSeasonName()
{
return seasonName;
}
public String getSeasonDes()
{
return seasonDes;
}
//创建枚举类对象
public static final Season SPRING = new Season("spring","春天");
public static final Season SUMMER = new Season("summer","夏天");
public static final Season AUTUMN = new Season("autumn","秋天");
public static final Season WINTER = new Season("winter","冬天");
@Override
public String toString()
{
return "Season [seasonName=" + seasonName + ", seasonDes=" + seasonDes + "]";
}
public void show() {
System.out.println("this is a season!");
}
}
public class TestSeason
{
public static void main(String[] args)
{
Season spring = Season.SPRING;//创建对象
System.out.println(spring);
spring.show();
System.out.println(spring.getSeasonName());
System.out.println(spring.getSeasonDes());
}
}
Output:
Season [seasonName=spring, seasonDes=春天]
this is a season!
spring
春天
三.JDK1.5以后enum枚举关键字
以上JDK1.5以前的枚举类,书写的时候麻烦容易出现错误,因此1.5以后出现了enum枚举类。
3.1两种enum方式
Demo1:
public enum Season {
SPRING,
SUMMER,
AUTUMN,
WINTER;
}
Demo2:在开发中枚举可以用来定义常量
public enum Season
{
SPRING("spring","春天"),
SUMMER("summer","夏天"),
AUTUMN("autumn","秋天"),
WINTER("winter","冬天");
private String seasonName;
private String seasonDes;
Season(String seasonName,String seasonDes) { //去掉public修饰符
this.seasonName=seasonName;
this.seasonDes=seasonDes;
}
public String getSeasonName()
{
return seasonName;
}
public void setSeasonName(String seasonName)
{
this.seasonName = seasonName;
}
public String getSeasonDes()
{
return seasonDes;
}
public void setSeasonDes(String seasonDes)
{
this.seasonDes = seasonDes;
}
@Override
public String toString()
{
return "Season [seasonName=" + seasonName + ", seasonDes=" + seasonDes + "]";
}
}
注意⚠️:
- 枚举类型都隐式继承了java.lang.Enum类,因此不能继承其他类,但可以实现接口。
- 枚举类型只能有私有的构造方法(java运行时创建,外部不能进行实例化);
- 不能泛型化;
- 构造器没有修饰符(没有public,private……)
3.2常用方法
- values()方法:获取枚举类信息。
- valuesOf(String name)方法:传入枚举名称,返回对象。
public class TestSeason
{
public static void main(String[] args)
{
//values()
Season[] seasons =Season.values();
for(int i=0;i<seasons.length;i++) {
System.out.println(seasons[i]);
}
System.out.println("------------");
//valuesOf()
String str ="SPRING";
Season sea = Season.valueOf(str);
System.out.println(sea);
}
}
Output:
Season [seasonName=spring, seasonDes=春天]
Season [seasonName=summer, seasonDes=夏天]
Season [seasonName=autumn, seasonDes=秋天]
Season [seasonName=winter, seasonDes=冬天]
------------
Season [seasonName=spring, seasonDes=春天]
- 实现接口方式1⃣️:(普通方法)
interface Info{
void show();
}
public enum Season implements Info
{
.
.
.
.
.
//在枚举类中重写show方法
@Override
public void show() {
System.out.println("this is a season!");
}
}
测试类创建对象调用show方法:
public class TestSeason
{
public static void main(String[] args)
{
Season spring=Season.SPRING;
spring.show();
}
}
Output:
this is a season!
- 实现接口方式2⃣️:(特有方法)
可以让不同的枚举对象调用被重写的方法,相当于每个对象重写方法。
interface Info{
void show();
}
public enum Season implements Info
{
SPRING("spring","春天"){
public void show() {
System.out.println("this is spring!");
}
},
SUMMER("summer","夏天"){
public void show() {
System.out.println("this is summer!");
}
},
AUTUMN("autumn","秋天"){
public void show() {
System.out.println("this is autumn!");
}
},
WINTER("winter","冬天"){
public void show() {
System.out.println("this is winter!");
}
};
private String seasonName;
private String seasonDes;
Season(String seasonName,String seasonDes) {
this.seasonName=seasonName;
this.seasonDes=seasonDes;
}
public String getSeasonName()
{
return seasonName;
}
public void setSeasonName(String seasonName)
{
this.seasonName = seasonName;
}
public String getSeasonDes()
{
return seasonDes;
}
public void setSeasonDes(String seasonDes)
{
this.seasonDes = seasonDes;
}
}
测试类:
public class TestSeason
{
public static void main(String[] args)
{
Season spring=Season.SPRING;
spring.show();
Season summer=Season.SUMMER;
summer.show();
Season winter=Season.WINTER;
winter.show();
Season autumn=Season.AUTUMN;
autumn.show();
}
}
Output:
this is spring!
this is summer!
this is winter!
this is autumn!
- switch
JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。
enum Signal {
GREEN, YELLOW, RED
}
public class TrafficLight {
Signal color = Signal.RED;
public void changeSignal() {
switch (color) {
case RED:
color = Signal.GREEN;
break;
case YELLOW:
color = Signal.RED;
break;
case GREEN:
color = Signal.YELLOW;
break;
}
}
}