java枚举学习总结

来源:互联网 发布:高仿巴宝莉风衣 知乎 编辑:程序博客网 时间:2024/05/22 00:37

需求描述: 

假设有一个方法,入参为表示颜色的数字或者字符串,我们只针对特定的颜色执行一定的程序逻辑,要求1:表示红色;2:表示蓝色;3表示黄色,我们和调用我们接口的另一端程序做个约定,让他只能填入(1,2,3)几个值; 

在没有正式应用枚举之前,我们可以自己写java类模拟枚举的功能:


通过接口的方式实现枚举功能: 

package com.enumtest.learning; 

/**

 * 通过接口方式完成类似枚举类型的功能

 *

 * @author Administrator

 *

 */

public class Color {   

    public final static ColorType RED =new Red(1);

    public final static ColorType BLUE =new Blue(2);

    public final static ColorType YELLOW =new Yellow(3); 

    /**

     * 定义一个内部接口

     * @author Administrator

     *

     */

    public static interface ColorType {

       int getColor();

    }   

    /**

     * 接口的实现类为最终态的(final

     * @author Administrator

     *

     */ 

    final static class Red implements ColorType {

       private int color = 0;

 

       public Red(int color) {

           this.color = color;

       }

 

       @Override

       public int getColor() {

           // TODO Auto-generatedmethod stub

           return this.color;

       }

 

    }

 

    final static class Blue implements ColorType {

       private int color = 0;

 

       public Blue(int color) {

           this.color = color;

       }

 

       @Override

       public int getColor() {

           // TODO Auto-generatedmethod stub

           return this.color;

       }

 

    }

 

    final static class Yellow implements ColorType {

       private int color = 0;

 

       public Yellow(int color) {

           this.color = color;

       }

 

       @Override

       public int getColor() {

           // TODO Auto-generatedmethod stub

           return this.color;

       }

    }

   

}

 

测试上面定义的通过接口模拟的枚举功能

package com.enumtest.learning;

 

import com.enumtest.learning.Color.ColorType;

 

public class WithClass {

   

    public void printColor(ColorType type){

      

       switch (type.getColor()) {

       case 1:

           System.out.println("红色");

           break;

       case 2:

           System.out.println("绿色");

           break;

       case 3:

           System.out.println("黄色");

           break;

 

       default:

           break;

       }

      

    }

 

    /**

     * @param args

     */

    public static void main(String[] args) {

       // TODO Auto-generatedmethod stub

       WithClass wc=new WithClass();

       wc.printColor(Color.RED);

       wc.printColor(Color.BLUE);

       wc.printColor(Color.YELLOW);

 

    }

 

}

 

总结:

我们将ColorType的子类设计为内部类,并且是final状态是为了防止外部程序进行集成,重载,可以看出,上述代码中printColor基本上没有参数类型判断的代码,只是一个分支流程的控制而已!我们距离目标越来越近了,但是不难发现,如果调用者自己实现了ColorType接口,那么它也可以浑水摸鱼将非法的类型传递进来,在5.0之前我们通过类的定义肯定是能够完全实现,只需要对上述代码进行一些简单的修改即可,比如说将参数类设计为不可继

承的,内部有很多实例变量,由于我们重点说明的是枚举,在这里我们将不在进行介绍,感兴趣的读者可以在网上查阅或者和我交流;

 

通过抽象类模拟枚举功能的实现

 

package com.enumtest.learning;

 

/**

 * 基于抽象类模拟枚举功能的实现

 * @author Administrator

 *

 */

public abstract class Sex {

    int value;

   

    /**

     * 构造函数私有化保证外部不能对该类进行实例化

     * @param value

     */

    private Sex(int value) {

       this.value = value;

    }

   

    public final static Sex MAN=new Sex(1) {

      

       @Override

       public int getValue() {

           // TODO Auto-generatedmethod stub

           return this.value;

       }

    };

   

    public final static Sex WOMAN=new Sex(2) {

      

       @Override

       public int getValue() {

           // TODO Auto-generatedmethod stub

           return this.value;

       }

    };

   

    /**

     * 定义一个获得属性值的抽象方法

     * @return

     */

    public abstract int getValue();

 

}

测试上面定义的通过接口模拟的枚举功能

package com.enumtest.learning;

 

public class WithSex {

   

    public void printSex(Sex sex){

       switch (sex.getValue()){

       case 1:

           System.out.println("男性");

           break;

       case 2:

           System.out.println("女性");

           break;

       default:

           break;

       }

    }

 

    /**

     * @param args

     */

    public static void main(String[] args) {

       // TODO Auto-generatedmethod stub

       WithSex sex=new WithSex();

       sex.printSex(Sex.MAN);

       sex.printSex(Sex.WOMAN);      

 

    }

 

}

 

正式通过枚举来实现这个功能

定义一个枚举

package com.enumtest.learning;

 

public enum ColorEnum{

    RED,BLUE,YELLOW;

 

}

 

应用这个枚举:

package com.enumtest.learning;

 

public class WithEnum {

   

    public void printColor(ColorEnum color){

       switch (color) {

       case RED:

           System.out.println("红色");

           break;

       case BLUE:

           System.out.println("蓝色");

           break;

       case YELLOW:

           System.out.println("黄色");

           break;

       }

    }

 

    /**

     * @param args

     */

    public static void main(String[] args) {

       // TODO Auto-generatedmethod stub

       WithEnum we=new WithEnum();

       we.printColor(ColorEnum.RED);

       we.printColor(ColorEnum.BLUE);

       we.printColor(ColorEnum.YELLOW);

 

    }

 

}

在printColor方法中,我们的入参只能为Color中的三个枚举值,否则在编译阶段就不能通过,这样就实现了在入参时期进行规则校验的目的;

 


枚举的构造函数,方法,以及字段

应用场景:

假设有这样一个枚举值Grade,其中A代表(90~100)B(80~89)C(70~79)D(60~69)E(0~59),我们除了用Grade控制入参之外,我们还想知道他代表的另外一层意思也就是数字的区间,如此这般,我们应该如何是好?

 

package com.enumtest.learning; 

/**

 * 枚举可以定义属性字段和方法以及构造方法

 * @author Administrator

 *

 */

public enum Grade {

   

    A("90~100"),B("80~89"),C("70~79"),D("60~69"),E("0~59");

   

    //枚举属性字段

    private Stringvalue;

   

    //枚举构造方法必须为private

    private Grade(String value) {

       this.value = value;

    }

   

    //枚举方法

    public String getValue() {

       returnvalue;

    }

 

}

 

 

枚举测试:

package com.enumtest.learning;

 

public class GradeEnumTest {

   

    public void printMessage(Grade grade){

       System.out.println(grade.getValue());

    }

 

    /**

     * @param args

     */

    public static void main(String[] args) {

       // TODO Auto-generatedmethod stub

       GradeEnumTest ge=new GradeEnumTest();

       ge.printMessage(Grade.A);

       ge.printMessage(Grade.B);

       ge.printMessage(Grade.C);

       ge.printMessage(Grade.D);

       ge.printMessage(Grade.E); 

    } 

}

 

总结一下

Ø枚举类型的枚举值其实就是枚举类型的实例(静态)

Ø 枚举类型的构造函数必须是private的

 

枚举的抽象方法:

package com.enumtest.learning;

 

public enum GradeOfAbstract {

   

    A("90~100"){ 

       @Override

       public String getLocalValue() {

           // TODO Auto-generatedmethod stub

           return"优秀";

       }      

    },

    B("80~89"){ 

       @Override

       public String getLocalValue() {

           // TODO Auto-generatedmethod stub

           return"良好";

       }      

    },

    C("70~79"){ 

       @Override

       public String getLocalValue() {

           // TODO Auto-generatedmethod stub

           return"中等";

       }      

    },

    D("60~69"){ 

       @Override

       public String getLocalValue() {

           // TODO Auto-generatedmethod stub

           return"";

       }      

    },

    E("0~59"){ 

       @Override

       public String getLocalValue() {

           // TODO Auto-generatedmethod stub

           return"未及格";

       }      

    };

   

    private Stringvalue;

   

    private GradeOfAbstract(String value) {

       this.value = value;

    }

 

    public String getValue() {

       returnvalue;

    }

   

    public abstract String getLocalValue();

 

}

 

测试:

package com.enumtest.learning;

 

public class AbstractEnumTest {

   

    public static void printLocalValue(GradeOfAbstract grade){

       System.out.println(grade.getLocalValue());

    }

 

    /**

     * @param args

     */

    public static void main(String[] args) {

       // TODO Auto-generatedmethod stub

       AbstractEnumTest.printLocalValue(GradeOfAbstract.A);

       AbstractEnumTest.printLocalValue(GradeOfAbstract.B);

       AbstractEnumTest.printLocalValue(GradeOfAbstract.C);

       AbstractEnumTest.printLocalValue(GradeOfAbstract.D);

       AbstractEnumTest.printLocalValue(GradeOfAbstract.E);

 

    }

 

}

输出结果:

优秀

良好

中等

未及格 

 


枚举类型可以实现接口或者集成抽象类

枚举类是final的,因为它不允许被继承,这也就解释了他必须实现抽象类中的全部抽象方法

 

简短的总结:

1)   枚举类型可以规范和约束运行时程序函数入参;

2)  枚举其实就是一个特殊的Class;

3)  Object有的方法他都有,因为它是Object的子类;

4)  枚举类型其实是一个final类型的类,所以他不能被继承;

5)  枚举类型不仅可以定义枚举值,它还可以定义构造函数,方法以及属性字段;

6)  枚举类型的构造函数必须是私有的,这个不难理解,因为如果是可见的话,它就不能起到规范和约束的作用;

7)  枚举类型允许有抽象函数; 

8)   枚举类型可以实现继承其他接口或者抽象类; 

9)   每一个枚举常量都是public static final

原创粉丝点击