Java语言从设计之初并没有提供枚举的概念,所以开发者不得不使用多例设计模式来代替枚举的解决方案,从JDK1.5开始,Java支持了枚举结构的定义,通过枚举简化多例设计的实现。
1.定义枚举类:
JDK1.5开始,Java提供了一个新的关键字:enum,利用此关键字可以实现枚举类型的定义,简化多例设计模式的定义。
package cn.kuiba.util;
enum Color{ //枚举类
RED,GREEN,BLUE; //实例化对象
}
public class Main {
public static void main(String args[]){
Color c=Color.RED; //获取实例化对象
System.out.println(c); //输出对象
}
}
执行结果:RED
本程序定义了一个Color的枚举类,同多例设计模式一样,提供三个实例化对象,可以在外部直接利用枚举名称进行对象的调用
提示:关于枚举名称的定义。 在本程序中,所有的枚举类的对象名称全部采用了大写字母的定义,符合多例设计模式要求,也可以采用中文的形式定义。
枚举除了简化多例设计模式之外,也提供了方便的信息获取操作,利用“枚举类.values()”结构就可以以对象数组的形式获取枚举中的全部对象。
范例:输出枚举中的全部内容
package cn.kuiba.util;
enum Color{ //枚举类
RED,GREEN,BLUE; //实例化对象
}
public class Main {
public static void main(String args[]){
for (Color c:Color.values()){ //foreach输出全部枚举对象
System.out.println(c+"、"); //输出枚举对象信息
}
}
}
执行结果:RED、GREEN、BLUE
本程序利用values()方法获取了Color中的全部枚举对象,随后利用foreach循环获取每一个对象并进行输出。
之所以采用枚举来代替多例设计模式的一个很重要的原因在于,可以直接在switch语句中进行枚举对象类型判断。
范例:在switch中判断枚举类型
package cn.kuiba.util;
enum Color{ //枚举类
RED,GREEN,BLUE; //实例化对象
}
public class Main {
public static void main(String args[]){
Color c=Color.RED;
switch (c){ //支持枚举判断
case RED: //匹配内容
System.out.println("红色");
break;
case GREEN: //匹配内容
System.out.println("绿色");
break;
case BLUE: //匹配内容
System.out.println("蓝色");
break;
}
}
}
执行结果:红色
本程序直接在switch中可以实现枚举对象的匹配,而如果使用多例设计模式,则只能通过大量的if语句的判断来进行内容的匹配与结果输出。
提示:关于switch允许操作的数据类型。
1.在JDK1.5之前,只支持Int或Char型数据。
2.在JDK1.5之后,增加Enum型数据。
3.在JDK1.7之后,增加String型数据。
2.Enum类
枚举并不是一个新的类型,它只是提供了一种更为方便的结构。严格来讲,每一个使用enum定义的类实际上都属于一个类继承了Enum父类而已,而java.lang.Enum类定义如下。
Public abstract class Enum<E extends Enum<E>>
extends Object implements Comparable<E>,Serializable{}
在Enum类中定义其可以支持的泛型上限,同时在Enum类中提供如表所示的常用方法。
通过表可以知道Enum类中的构造方法使用了protected访问权限,实际上这也属于构造方法的封装实现,同时在实例化每一个枚举类对象时都可以自动传递一个对象名称和序号。
范例:观察enum关键字与Enum类之间的联系
package cn.kuiba.util;
enum Color{ //枚举类
RED,GREEN,BLUE; //实例化对象
}
public class Main {
public static void main(String args[]){
for (Color c:Color.values()){ //获取枚举信息
System.out.println(c.ordinal()+"-"+c.name());
}
}
}
执行结果
0-RED
1-GREEN
2-BLUE
在本程序中每输出一个枚举类对象时都调用了Enum类中定义的ordinal()和name()方法来获取相应的信息,所以可以证明,enum定义的枚举类将默认继承Enum父类。
3.定义枚举结构
在枚举类中除了可以定义若干个实例化对象之外,也可以像普通类那样定义成员属性、构造方法、普通方法,但需要知道,枚举的本质是多例设计模式,所以构造方法不允许使用public进行定义。如果类中没有提供无参构造方法,则必须在定义每一个枚举对象时明确传入参数内容。
范例:在枚举类中定义成员属性与方法
package cn.kuiba.util;
enum Color{ //枚举类
RED("红色"),GREEN("绿色"),BLUE("蓝色"); //枚举对象要写在首行
private String title; //成员属性
private Color(String title){ //构造方法初始化属性
this.title=title;
}
@Override
public String toString(){ //输出对象信息
return this.title;
}
}
public class Main {
public static void main(String args[]){
for (Color c:Color.values()){ //获取枚举信息
System.out.println(c.ordinal()+"-"+c.name()+"-"+c);
}
}
}
执行结果
0-RED-红色
1-GREEN-绿色
2-BLUE-蓝色
本程序在枚举结构中定义了构造方法并且覆写了Object类中的toString()方法,可以发现在Java中已经将枚举结构的功能进行了扩大,使其与类结构更加贴近。
范例:通过枚举类实现接口
package cn.kuiba.util;
interface IMessage{
public String getMessage(); //获取信息
}
enum Color implements IMessage{ //枚举类实现接口
RED("红色"),GREEN("绿色"),BLUE("蓝色"); //枚举对象要写在首行
private String title; //成员属性
private Color(String title){ //构造方法初始化属性
this.title=title;
}
@Override
public String toString(){ //输出对象信息
return this.title;
}
@Override
public String getMessage(){ //方法覆写
return this.title;
}
}
public class Main {
public static void main(String args[]){
IMessage msg=Color.RED; //对象向上转型
System.out.println(msg.getMessage());
}
}
执行结构:
红色
本程序让枚举类实现了IMessage接口,这样就需要在枚举类中覆写接口中的抽象方法,由于Color是IMessage接口子类,所以每一个枚举类对象都可以向上转型实现接口对象实例化 枚举还可以直接进行抽象方法的定义,此时可以在每一个枚举对象中分别实现此抽象方法。
范例:在枚举中定义抽象方法
package cn.kuiba.util;
enum Color{
RED("红色"){
@Override
public String getMessage(){
return "【RED】"+this;
}
},GREEN("绿色"){
@Override
public String getMessage(){
return "【绿色】"+this;
}
},BLUE("蓝色"){
@Override
public String getMessage(){
return "【蓝色】"+this;
}
};
private String title;
private Color(String title){
this.title=title;
}
@Override
public String toString(){
return this.title;
}
public abstract String getMessage();
}
public class Main {
public static void main(String args[]){
System.out.println(Color.RED.getMessage());
}
}
执行结果:
【RED】红色
本程序在枚举中利用了abstract关键字定义了一个抽象方法。
4.枚举应用案例
枚举主要是定义了实例化对象的使用范围,同时枚举类型也可以作为成员属性类型。
范例:枚举结构应用
package cn.kuiba.util;
enum Sex{ //性别
MALE("男"),FEMALE("女"); //枚举对象
private String title; //成员属性
private Sex(String title){ //构造方法
this.title=title;
}
@Override
public String toString() { //获取对象信息
return this.title;
}
}
class Person{ //普通类
private String name; //姓名
private int age; //年龄
private Sex sex; //性别
public Person(String name,int age,Sex sex){ //构造方法
this.name=name; //属性初始化
this.age=age;
this.sex=sex;
}
@Override
public String toString() {
return "姓名:"+this.name+"、年龄:"+this.age+"、性别:"+this.sex;
}
}
public class Main {
public static void main(String args[]){
System.out.println(new Person("张三",20,Sex.MALE));
}
}
执行结果:
姓名:张三、年龄:20、性别:男
本程序定义Person类时使用了枚举类型,在实例化Person类对象时就可以限定Sex对象的取值范围。(现在定义一个Person类,里面需要提供有性别属性,并且不希望被外界用户随意更改,所以使用枚举最合适)。