黑马程序员_枚举

来源:互联网 发布:美工简历怎么写 编辑:程序博客网 时间:2024/06/07 15:10

知识点纲要:

枚举概念、用普通类模拟枚举的实现原理、用Enum类创建枚举、带构造方法的枚举、带抽象方法的枚举、枚举与单例设计模式

1.枚举概念

张孝祥老师说到:枚举就是要让某个类型的变量的取值只能为若干固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译时就可以控制源程序中填写的非法值,而采用普通变量的方式在开发阶段无法实现这一目标。

我对此是这样理解的,枚举就是一个特殊的对象,这个对象的构造方法是私有的,不能通过new来实例化,这个对象会提供一个或多个指向本类或者子类的静态成员常量来实例化对象,这样做只有一个目的,那就是保证了他人在使用本类时,只能创建指定的对象。

2.用普通类模拟枚举的实现原理

要自定义一个枚举类,就要保证:
(1) 私有化所有构造方法,确保不能通过new的方式来创建对象
(2) 该类所有实例都要用public static final来修饰,即公有,可以通过类访问,不能修改
(3) 使用private final修饰字段,既然枚举是为了让别人创建指定的对象,那么这些对象中的字段就不应该被修改

例如,周末有周六周日两天,在创建周末Weekend这种类型的变量时,其取值范围只能是周六或周日,写成代码就是这样的

public class Weekend {private final String name;// 用private final修饰字段// 私有化构造方法private Weekend(String name) {this.name = name;}public static final Weekend SAT = new Weekend("星期六"); // 创建指向本类的静态成员常量SATpublic static final Weekend SUN = new Weekend("星期天");// 创建指向本类的静态成员常量SUN// 覆盖toString()方法public String toString() {return this == SAT ? SAT.name : SUN.name;}}
这样在创建Weekend类型的变量时,就只能通过以下方式实例化Weekend对象

Weekend w1 = Weekend.SAT;Weekend w2 = Weekend.SUN;

3.用Enum类创建枚举

在jdk1.5之后,创建一个枚举就变得很简单,可以直接使用Enum类来创建,例如

public enum Weekend {// 用逗号隔开,如果所有元素后还有内容则必须加;SAT, SUN;}
Enum类中常用的函数

int compareTo(E o) 比较当前和传入的对象在枚举中的顺序,参数在当前对象前则返回1,相等返回0,在之后则返回-1。

String name() 返回当前对象对应的静态成员常量的名字

int ordinal() 返回当前对象在枚举中的角标

public static valueOf(Class<T> enumType, String name) 根据传入的枚举类字节码enumType和字符串name返回对应的对象

values() 返回一个数组,包含枚举中的所有对象

4.带构造方法的枚举

(1) Enum枚举中也可以有一个或多个构造方法,不过这些构造方法必须是私有的

(2) 构造方法必须写在枚举中所有元素之后,且此时最后一个元素后面一定要加分号

(3) 使用构造方法时使用element(参数)的形式,默认使用不带参数的构造方法

public enum Weekend {SAT, SUN(1); // SUN调用带参数的构造方法,SAT调用默认构造方法private Weekend() {System.out.println(this.name()+"使用的是不带参数的构造方法");}private Weekend(int n) {System.out.println(this.name()+"使用的是带参数的构造方法");}}

在主函数中创建两个Weekend对象

Weekend w1 = Weekend.SAT;Weekend w2 = Weekend.SUN;

运行会输出以下结果

SAT使用的是不带参数的构造方法

SUN使用的是带参数的构造方法

5.带抽象方法的枚举

带有抽象方法的类,必须由其子类实现抽象方法,然后才可以被实例化。对于枚举来说,亦是如此。也就是说,如果枚举中含有抽象方法,那么该枚举中的元素就必须是其子类。

例如,对于交通灯这个对象,它在实例化时的取值应该是红灯,绿灯或黄灯,所以可以设计成一个枚举,但红灯,黄灯和绿灯又有不同的显示时间,以及下一个显示的灯也不同,这时就可以将这些元素设计为交通灯的子类。

public enum Lamp {
<span style="white-space:pre"></span>//创建红灯元素,通过内部类的形式覆盖抽象方法<span style="font-family: Arial, Helvetica, sans-serif;">nextLamp()</span>RED(30) {public Lamp nextLamp() {return GREEN;}},
<pre name="code" class="java"><span style="white-space:pre"></span>//创建绿灯元素,通过内部类的形式覆盖抽象方法<span style="font-family: Arial, Helvetica, sans-serif;">nextLamp()</span>
GREEN(30) {public Lamp nextLamp() {return YELLOW;}},
<pre name="code" class="java"><span style="white-space:pre"></span>//创建黄灯元素,通过内部类的形式覆盖抽象方法<span style="font-family: Arial, Helvetica, sans-serif;">nextLamp()</span>
YELLOW(2) {public Lamp nextLamp() {return RED;}};public abstract Lamp nextLamp(); // 将下一个要显示的灯的方法抽象
<span style="white-space:pre"></span>// 让元素初始化时就具备显示时间private final int time;private Lamp(int time) {this.time = time;}}

6.枚举与单例设计模式

当枚举中只有一个元素时,可以作为一种单例的实现方式。因为枚举中的元素都是静态常量,它的特点是在内存中只有一个,JAVA虚拟机加载类的时候为其分配内存,位于方法区,被类的所有实例共享,其生命周期取决于类的生命周期,所以当只有一个元素时,就是一种单例。

public enum Weekend {SAT;}

创建如上一个只有一个元素的枚举,在主函数中创建两个Weekend对象并比较

Weekend w1 = Weekend.SAT;Weekend w2 = Weekend.SAT;System.out.println(w1==w2);

 输出结果为true,说明该枚举只能产生一个对象。

0 0
原创粉丝点击