TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
枚举是java5(Tiger)中新增的一种类型,这个类型是为了弥补Java不支持枚举类型的遗憾。
首先,给大家枚举一个总的印象。枚举是一种特殊的 “类”,不是一种接口,它的枚举值都是一个枚举类型的实例。下面我们来具体讲讲枚举。
一、创建一个枚举
package com.mercy.tiger;
public enum EnumOne {
One,TWO,Three
} 很简单,有点像创建一个类,事实上他就是“类”,特殊的“类”。看看第三行,这里是什么东西啊?其实枚举就是一些“常数”,这些常数在这个集合中。这里就是One,TWO,Three就在EnumOne集合中。这里值得说明的是,这三个都是EnumOne的实例,这就是枚举的特殊性。
怎么来用它呢?
public static void main(String[] args){
EnumOne one=EnumOne.One;
System.out.println(one);
// result : One
}
- 二、内置枚举
- 我们来写一个内置(写在一个类的内部)的枚举
- public class InnerEnum {
- private enum ALPHABEAT{A,B,C}
- public static void main(String[] args) {
- ALPHABEAT a=ALPHABEAT.A;
-
- }
- }
- 我们在这里可以看出ALPHABEAT是个静态枚举类型,所以在它前面加个static也没有关系.
复制代码 三、迭代枚举
我们在这之前,我们应该讲讲枚举的 “类”的特性,但是他又不是类(矛盾?)。 我们要迭代枚举的话,我们要用到这个静态方法values(),返回一个对应的枚举数组。
这个方法是JVM内部生成的,给所有的枚举类型的方法,所以枚举很特殊,有“类”性。
- public class Test{
- private enum ALPHABEAT{A,B,C}
- public static void main(String[] args) {
- for(ALPHABEAT a : ALPHABEAT.values())
- {
- System.out.println(a);
- }
- }
- }
复制代码 其结果是:
A
B
C
四、高级内容
恐怕在我们日常中使用了很多枚举,比如把枚举作为条件,比如在switch语句中 使用。 前面可能提示性地说到,枚举值是常量,所以可以作为swtich中的case条件。再用前面的例子:
ALPHABEAT a=ALPHABEAT.A;
switch(a) {
case ALPHABEAT.A:
case ALPHABEAT.B:
case ALPHABEAT.C:
}
很抱歉,这个例子是错的。你会问错在哪里啦?我告诉你的枚举引用是不能作为case条件的。所以我们只能这么做: switch(a){
//caseALPHABEAT.A:
//caseALPHABEAT.B:
//caseALPHABEAT.C:
case A:
case B:
case C:
}
好了,我们在说说枚举的“类”性...
1.添加方法:
public enum EnumWithMethod {
Enum1,Enum2,Enum3;
public String getName() {
return this.getName();
}
} 发现没有,还有this引用哦!你说它有类性吗?还有令你更吃惊的东西: 我们可以定义main方法,不行试试: public enum EnumWithMethod {
Enum1,Enum2,Enum3;
public String getName(){
return this.getName();
} public static void main(String[] args) {
EnumWithMethod e1=EnumWithMethod.Enum1;
System.out.println(e1.getName());
} } 一定可以编译,最好不要运行它,结果你会 很郁闷的!(这个原因,这里不说了)
- 2.实现接口:
- 枚举可以接口,肯定嘛,能够定义方法,肯定可以实现接口嘛。
- public enum EnumImplementsInferface implements ForImpl {
- E1,E2;
- public voidmethod()
- {
- //DO Nothing
- }
- }
- interface ForImpl{
- public voidmethod();
- }
复制代码 3.不能扩展与不能被扩展:
你会发现你的枚举在定义的时候不能extends其他的类,也不能被extends。
// enumA extends Object{}
// classExtendsEnum extends EnumImplementsInferface{}
自然你会想到这里方法不能是abstract的,其实方法都是final方法,不是吗?
对于为什么不能继承或者被继承,你可以去思考,我觉得应该两方面来看,正方:为什么要继承呢?枚举是常数集合,继承有什么用呢?我可以任意的取值,并且不需要通过继承来达到扩展的目的。反方:继承可以提高重用性,特别是一些方法的重用等等。所以,未来怎么走,看SUN的啦!
4.特殊规定:
若你比较细心或者有怀疑精神的话,你可能会发现枚举值只能在最前段定义, 方法等等都在后面定义,试试吧!
5.构造器:
枚举有构造器,但是构造器只能用private限定。默认也是private,这也就是说枚举通过new关键字不能实例化。
private Enum WithMethod() { }
6.特殊 “值”类:
既然有构造器,那么构造器就可以带参数,所以我们构造带有参数的实例。看下面的代码:
- public enum EnumVauleClass {
-
- EVC1("No.1"),EVC2("No.2"),EVC3("No.3");
- private String name;
- private EnumVauleClass(String name){
- this.name=name;
- }
- public String getName(){
- return name;
- }
- public static void main(String[] args)
- {
- EnumVauleClass evc1=EnumVauleClass.EVC1;
- System.out.println(evc1);
- }
- }
复制代码 这里我们可以看出来,我们实例化了三个实例变量EVC1-EVC3,看到14行,是否发现我们这里的实例并没有带有参数在main方法中!?其实这正是我们要说的我们的类实例是定义在枚举类里面的,我们仅仅引用一个常量实例。这里所说都是基础,为后面的“值”类做铺垫。 再说“值”类,我们改改代码:- public enum EnumVauleClass1 {
- EVC1("No.1") {
- public String getName() {
- return "I"m "+EVC1.name;
- }
- };
- private String name;
- private EnumVauleClass1(String name){
- this.name=name;
- }
- public String getName(){
- return name;
- }
-
- public static void main(String[] args) {
- EnumVauleClass1 evc1=EnumVauleClass1.EVC1;
- System.out.println(evc1.getName());
- }
- }
复制代码 若你对代码中2-6行的代码感到有问题,这是自然的! 我们在枚举里面好像定义了一个内部类似的,但是这个叫做“值”类,这是我的讲法。真正的名称“值限定” 类。再看看结果并不是No.1,而是I"mNo.1,证明这里是覆盖 了“父类”的方法getName(),嗯?其实我个人认为,SUN的做法是把全面面向对象发挥到个个方面。不多说了,最后我还告诉大家一个秘密,呵呵!
其实,我们说有的枚举都继承了java.lang.Enum类,前面说它不能继承的吗?
呵呵,你看看你的定义的枚举中,一定继承有Enum中的可继承的方法。
源码下载:http://file.javaxxz.com/2014/10/28/235557328.zip |
|