美文网首页
java枚举类

java枚举类

作者: 欢乐时光欢乐你我 | 来源:发表于2017-07-23 21:49 被阅读269次

    Java 枚举7常见种用法
    DK1.5引入了新的类型——枚举。在 Java 中它虽然算个“小”功能,却给我的开发带来了“大”方便。
    用法一:常量
    在JDK1.5 之前,我们定义常量都是: public static fianl.... 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。

    Java代码

    public enum Color {
    RED, GREEN, BLANK, YELLOW
    }

    用法二:switch
    JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。

    Java代码

    enum Signal {
    GREEN, YELLOW, RED
    }
    public class TrafficLight {
    Signal color = Signal.RED;
    public void change() {
    switch (color) {
    case RED:
    color = Signal.GREEN;
    break;
    case YELLOW:
    color = Signal.RED;
    break;
    case GREEN:
    color = Signal.YELLOW;
    break;
    }
    }
    }

    用法三:向枚举中添加新方法
    如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例。

    Java代码

    public enum Color {
    RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
    // 成员变量
    private String name;
    private int index;
    // 构造方法
    private Color(String name, int index) {
    this.name = name;
    this.index = index;
    }
    // 普通方法
    public static String getName(int index) {
    for (Color c : Color.values()) {
    if (c.getIndex() == index) {
    return c.name;
    }
    }
    return null;
    }
    // get set 方法
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public int getIndex() {
    return index;
    }
    public void setIndex(int index) {
    this.index = index;
    }
    }

    用法四:覆盖枚举的方法
    下面给出一个toString()方法覆盖的例子。

    Java代码

    public enum Color {
    RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
    // 成员变量
    private String name;
    private int index;
    // 构造方法
    private Color(String name, int index) {
    this.name = name;
    this.index = index;
    }
    //覆盖方法
    @Override
    public String toString() {
    return this.index+"_"+this.name;
    }
    }

    用法五:实现接口
    所有的枚举都继承自java.lang.Enum类。由于Java 不支持多继承,所以枚举对象不能再继承其他类。

    Java代码

    public interface Behaviour {
    void print();
    String getInfo();
    }
    public enum Color implements Behaviour{
    RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
    // 成员变量
    private String name;
    private int index;
    // 构造方法
    private Color(String name, int index) {
    this.name = name;
    this.index = index;
    }
    //接口方法
    @Override
    public String getInfo() {
    return this.name;
    }
    //接口方法
    @Override
    public void print() {
    System.out.println(this.index+":"+this.name);
    }
    }

    用法六:使用接口组织枚举

    Java代码

    public interface Food {
    enum Coffee implements Food{
    BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO
    }
    enum Dessert implements Food{
    FRUIT, CAKE, GELATO
    }
    }

    用法七:关于枚举集合的使用
    java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的 key是enum类型,而value则可以是任意类型。关于这个两个集合的使用就不在这里赘述,可以参考JDK文档。
    关于枚举的实现细节和原理请参考:
    参考资料:《ThinkingInJava》第四版
    http://softbeta.iteye.com/blog/1185573

    二、为什么不用静态常量来替代枚举类呢?
    public static final int SEASON_SPRING = 1; public static final int SEASON_SUMMER = 2; public static final int SEASON_FALL = 3; public static final int SEASON_WINTER = 4;

    枚举类更加直观,类型安全。使用常量会有以下几个缺陷:
      1. 类型不安全。若一个方法中要求传入季节这个参数,用常量的话,形参就是int类型,开发者传入任意类型的int类型值就行,但是如果是枚举类型的话,就只能传入枚举类中包含的对象。
      2. 没有命名空间。开发者要在命名的时候以SEASON_开头,这样另外一个开发者再看这段代码的时候,才知道这四个常量分别代表季节。
    三、枚举类入门
      先看一个简单的枚举类。
    package enumcase;

    public enum SeasonEnum {
    SPRING,SUMMER,FALL,WINTER;
    }

    enum和class、interface的地位一样
    使用enum定义的枚举类默认继承了java.lang.Enum,而不是继承Object类。枚举类可以实现一个或多个接口。
    枚举类的所有实例都必须放在第一行展示,不需使用new 关键字,不需显式调用构造器。自动添加public static final修饰。
    使用enum定义、非抽象的枚举类默认使用final修饰,不可以被继承。
    枚举类的构造器只能是私有的。

    四、枚举类介绍
      枚举类内也可以定义属性和方法,可是是静态的和非静态的。
    package enumcase;

    public enum SeasonEnum {
    SPRING("春天"),SUMMER("夏天"),FALL("秋天"),WINTER("冬天");

    private final String name;
    
    private SeasonEnum(String name)
    {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
    

    }

    实际上在第一行写枚举类实例的时候,默认是调用了构造器的,所以此处需要传入参数,因为没有显式申明无参构造器,只能调用有参数的构造器。
      构造器需定义成私有的,这样就不能在别处申明此类的对象了。枚举类通常应该设计成不可变类,它的Field不应该被改变,这样会更安全,而且代码更加简洁。所以我们将Field用private final修饰。

    五、枚举类实现接口
      枚举类可以实现一个或多个接口。与普通类一样,实现接口的时候需要实现接口中定义的所有方法,若没有完全实现,那这个枚举类就是抽象的,只是不需显式加上abstract修饰,系统化会默认加上。
      
    package enumcase;

    public enum Operation {
    PLUS{

        @Override
        public double eval(double x, double y) {
            return x + y;
        }
        
    },
    MINUS{
    
        @Override
        public double eval(double x, double y) {
            return x - y;
        }
        
    },
    TIMES{
    
        @Override
        public double eval(double x, double y) {
            return x * y;
        }
        
    },
    DIVIDE{
    
        @Override
        public double eval(double x, double y) {
            return x / y;
        }
        
    };
    
    /**
     * 抽象方法,由不同的枚举值提供不同的实现。
     * @param x
     * @param y
     * @return
     */
    public abstract double eval(double x, double y);
    
    public static void main(String[] args) {
        System.out.println(Operation.PLUS.eval(10, 2));
        System.out.println(Operation.MINUS.eval(10, 2));
        System.out.println(Operation.TIMES.eval(10, 2));
        System.out.println(Operation.DIVIDE.eval(10, 2));
    }
    

    }

    Operatio类实际上是抽象的,不可以创建枚举值,所以此处在申明枚举值的时候,都实现了抽象方法,这其实是匿名内部类的实现,花括号部分是一个类体。我们可以看下编译以后的文件。

      
      共生成了五个class文件,这样就证明了PLUS,MINUS,TIMES,DIVIDE是Operation的匿名内部类的实例。

    六、switch语句里的表达式可以是枚举值
      Java5新增了enum关键字,同时扩展了switch。
    package enumcase;

    public class SeasonTest {
    public void judge(SeasonEnum s)
    {
    switch(s)
    {
    case SPRING:
    System.out.println("春天适合踏青。");
    break;
    case SUMMER:
    System.out.println("夏天要去游泳啦。");
    break;
    case FALL:
    System.out.println("秋天一定要去旅游哦。");
    break;
    case WINTER:
    System.out.println("冬天要是下雪就好啦。");
    break;
    }
    }

    public static void main(String[] args) {
        SeasonEnum s = SeasonEnum.SPRING;
        SeasonTest test = new SeasonTest();
        test.judge(s);
    }
    

    }

    相关文章

      网友评论

          本文标题:java枚举类

          本文链接:https://www.haomeiwen.com/subject/xatvkxtx.html