枚举
枚举属于加强版的多例设计模式
多例设计模式与枚举
多例设计模式的本质在于构造方法的私有化。而后在类的内部产生若干个实例化对象,随后利用一个 static 静态方法进行指定实例化对象的获得
范例:多例
package cn.mysterious; public class Enumeration { public static void main(String[] args) { Color redInstance = Color.getInstance(0); System.out.println(redInstance); } } class Color{ private static final Color RED = new Color("red"); private static final Color GREEN = new Color("green"); private static final Color BLUE = new Color("blue"); private String title; private Color(String title){ this.title = title; } private void getInstance(int ch) { // TODO Auto-generated method stub switch (ch) { case 0 : return RED; case 1 : return GREEN; case 2 : return BLUE; default : return null; } } public String toString() { // TODO Auto-generated method stub return this.title; } }
这个时候有人开始考虑了,多例实现的太麻烦了。多例设计是在JDK1.5之前出现的主要设计模式,其主要的目的是为了解决java缺少枚举带来的影响
如果在JDK1.5之后,多例的设计可以变为如下形式:
package cn.mysterious; public class Enumeration { public static void main(String[] args) { Color redInstance = Color.RED; System.out.println(redInstance); } } enum Color{ RED,GREEN,BLUE; }
用枚举搞一个结构其最终的效果和多例是一样的,所以枚举的主要功能是替代多例设计
Enum 与 enum
在JDK1.5之后追加有enum 关键字,那么这个关键字的主要目的是进行枚举定义
但是使用enum严格来讲并不算是一种所谓的新结构它只不过是相当于定义一个类,并且这个类默认继承了Enum父类
Enum类的定义观察:
public abstract class Enum<E extends Enum<E>>
extends Object
implements Comparable<E>, Serializable
Enum类里面允许使用的属性的类型必须是Enum 类或其子类的类型
但是这一操作基本上我们不需要去关注,对应的类型(RED,GREEN,BLUE,都是Color 的对象,而Color是一个枚举,枚举继承Enum)
而在Enum类中提供有一个构造方法:protected Enum(String name,int ordinal)
protected 是一个封装性,证明此时的Enum 构造方法值允许本包的类或不同的子类调用,在这个构造方法里面设置有 name (名字) 和 ordinal (编号)
这个构造也不是由你调用的,是由Enum 调用的
而在Enum类里面也提供有两个对应的方法:
获得对象的名字: public final String name()
获得对象的序号: public final int ordinal()
范例:在枚举类对象中使用以上两个方法:
package cn.mysterious; public class Enumeration { public static void main(String[] args) { Color redInstance = Color.RED; System.out.println(redInstance.name()); System.out.println(redInstance.ordinal()); } } enum Color{ RED,GREEN,BLUE; } /* 结果是 RED 0 */
默认的名字就是对象名字,序号就是对象定义的顺序
而将多例定义为枚举之后还可以取得全部对象信息,因为所有的枚举类中包含有一个 values() 方法,
这个方法可以以对象数据的形式返回全部枚举对象
范例:枚举取得全部对象
package cn.mysterious; public class Enumeration { public static void main(String[] args) { for (Color c: Color.values()) { System.out.println(c.ordinal()+ "=" + c.name()); } } } enum Color{ RED,GREEN,BLUE; }
面试题:请解释 enum 与 Enum 的区别?
enum是一个JDK1.5后追加的关键字,使用enum 可以定义枚举类,相当于定义一个类继承子Enum父类
在枚举中定义类结构
枚举hi在类的基础上发展起来的,所以枚举本身也可以进行构造方法,属性,普通方法的定义
但是需要注意的是:多例设计之中重点的要求“构造方法私有化(私有化不是简单的指 private ,还包括 default,protected )”
范例:定义枚举类型
package cn.mysterious; public class Enumeration { public static void main(String[] args) { for (Color c: Color.values()) { System.out.println(Color.BLUE);// 直接调用 toString() } } } enum Color{ GREEN("绿色"),RED("红色"),BLUE("蓝色"); // 对象要写在第一行 private String title; private Color(String title){ this.title = title; } public String toString(){ return this.title; } }
除了可以进行基本的结构定义之外,枚举里面还可以实现接口
范例:枚举实现接口
package cn.mysterious; public class Enumeration { public static void main(String[] args) { IMessage msg = Color.BLUE; // 对象向上转型 System.out.println(msg.getColor()); } } interface IMessage{ public String getColor(); } enum Color implements IMessage{ // 实现父接口 GREEN("绿色"),RED("红色"),BLUE("蓝色"); // 对象要写在第一行 private String title; private Color(String title){ this.title = title; } public String toString(){ return this.title; } @Override public String getColor() { // TODO Auto-generated method stub return this.title; } }
普通类是无法定义抽象的,但是枚举类里面可以定义抽象方法于是这个时候枚举的每一个实例化对象都必须去覆写此抽象方法
范例:枚举定义抽象方法
package cn.mysterious; public class Enumeration { public static void main(String[] args) { System.out.println(Color.BLUE.getColor()); } } enum Color { // 实现父接口 GREEN("绿色"){ public String getColor() { // TODO Auto-generated method stub return "绿色"; } },RED("红色"){ public String getColor() { // TODO Auto-generated method stub return "红色"; } },BLUE("蓝色"){ public String getColor() { // TODO Auto-generated method stub return "蓝色"; } }; // 对象要写在第一行 private String title; private Color(String title){ this.title = title; } public String toString(){ return this.title; } public abstract String getColor(); }
对以上的程序结构有些了解就可以了,java之中的枚举设计非常复杂,实际之中不需要那么复杂
枚举应用
下面通过一个简单的程序来观察枚举的使用
范例:定义一个描述用户的类。里面有用户的性别
package cn.mysterious; public class Enumeration { public static void main(String[] args) { Member mem = new Member("少公子",20,Sex.MALE);// 创建新用户 System.out.println(mem); } } class Member{ private String name; private int age; private Sex sex; public Member(String name,int age,Sex sex){ this.name = name; this.age = age; this.sex = sex; } public String toString(){ return "姓名:"+this.name+",年龄:"+this.age+",性别:"+this.sex; } } enum Sex{ MALE("男"),FEMALE("女"); private String title; private Sex(String title){ this.title = title; } public String toString(){ return this.title; } }
对于以上的操作,如果不使用枚举没有任何问题,所以对于枚举我们需要公正的认识它:如果你习惯于使用枚举开发,那么就继续用,如果没习惯,能看懂可以不用