Java中枚举类型(Enum)使用进阶

标签: Java

保留所有版权,请引用而不是转载本文(原文地址 https://yeecode.top/blog/08/ )。

本文是Java枚举类型的第三篇文章,对于枚举类型的实现原理和包含的方法特性不了解的小伙伴可以先去参考历史文章中的《Java中的枚举类型(Enum)详解》和《详解Java枚举类型(Enum)中的方法》两篇文章。

接下来,我们将深入了解枚举类的使用。

扩展枚举值与自定义构造函数

之前,我们讨论枚举类时,主要是针对最简单的枚举类型。每个枚举值只有一个字符串,如:

public enum Season {
    SPRING, SUMMER, AUTUMN, WINTER
}

但是实际使用中,我们可能想给每个枚举值赋予更多的含义,例如,给每个季节一个中文说明和编码等。

即实现:

SPRING("春天", 1201),
SUMMER("夏天", 1202),
AUTUMN("秋天", 1203),
WINTER("冬天", 1204);

那这样的操作是可以的么?答案是肯定的!可以操作。但是,因为最简单的枚举类型调用了默认的构造方法,如果我们要增加新的含义,则需要自己覆盖原来的构造方法。操作如下:

public enum Season {
    SPRING("春天", 1201),
    SUMMER("夏天", 1202),
    AUTUMN("秋天", 1203),
    WINTER("冬天", 1204);

    private String name;
    private Integer code;

    Season(String name, Integer code) {
        this.name = name;
        this.code = code;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    @Override
    public String toString() {
        return this.name() + "(" + this.code + ")";
    }
}

我们在枚举类中增加了name/code两个属性,并重新编写了构造方法。实现了我们的要求。

我们编写测试函数:

public class MainTest {
    public static void main(String[] args) {
        System.out.println(Season.AUTUMN.getName());
        System.out.println(Season.SPRING.toString());
    }
}

得到如下结果:

秋天
SPRING(1201)

关于覆盖enum类方法

我们知道,枚举类最终继承了java.lang.Enum抽象类,那么我们能够覆盖java.lang.Enum抽象类中的方法么?

这个当然是可以的。其实在上面的代码中,笔者已经覆盖了java.lang.Enum抽象类中的toString()方法,并得出了自定义的输出。

枚举类中定义抽象方法

既然编译器最终将每个枚举值声明为枚举类的实例,那我们能在枚举类中声明抽象方法让枚举值去实现么?

听起来有些不可思议,其实也是可以的。我们在枚举类Season中声明了一个抽象方法sayHello()。然后在创建枚举值时,就必须实现该抽象方法。最终的代码如下:

public enum Season {
    SPRING("春天", 1201) {
        @Override
        void sayHello() {
            System.out.println("hello spring!");
        }
    },
    SUMMER("夏天", 1202){
        @Override
        void sayHello() {
            System.out.println("hello summer!");
        }
    },
    AUTUMN("秋天", 1203){
        @Override
        void sayHello() {
            System.out.println("hello autumn!");
        }
    },
    WINTER("冬天", 1204){
        @Override
        void sayHello() {
            System.out.println("hello winter!");
        }
    };

    private String name;
    private Integer code;

    Season(String name, Integer code) {
        this.name = name;
        this.code = code;
    }

    abstract void sayHello();
}

然后运行以下测试代码:

public class MainTest {
    public static void main(String[] args) {
        Season.AUTUMN.sayHello();
    }
}

得到输出: hello autumn!

总结

通过这篇文章,我们知道在扩展了构造方法的情况下,我们可以为每个枚举值注入更多的属性。并且,枚举类作为java.lang.Enum抽象类的子类,可以重写父类的方法。同时,每个枚举值作为枚举对象的实例,可以实现枚举对象中定义的抽象方法。

最终,通过《Java中的枚举类型(Enum)详解》《详解Java枚举类型(Enum)中的方法》和本文,我们从原理、特性、使用三个方面对枚举类型进行详细的介绍,该系列到此结束。

大家有相关的问题需要讨论,可以留言互动。

本文首发于个人知乎:易哥(https://www.zhihu.com/people/yeecode),欢迎关注。

作者书籍推荐