日志文章

2007年09月24日 10:26:30

Java5新特征之新特征之枚举

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

    (下一章:ForEach语句)

    类别: J2SE开发经验 |  评论(-2) |  浏览(5715) |  收藏
    -22楼 [匿名]sdf34fsdsdf 2008年07月06日 05:20:48 Says:
    [url=http://www.jipiaoonline.cn]
    -23楼 [匿名]sdf34fsdsdf 2008年07月05日 03:20:42 Says:
    [url=http://www.jipiaoonline.cn]
    发表评论