你确定你真的懂了枚举吗?

背景:

​ 在工作中我们都会创建一些静态常量,例如:

// 春天
private static final String SPRING = 1;

这种定义方式看似十分简单,但是其实是存在很多问题的:

  • 就是在使用过程中,别的开发人员会把你定义的常量用作别的用途,比如上面可能会被用作与别的数相加等等;

所以这个时候就需要就需要使用枚举,java5新增了enum关键字(它与calss、interface关键字的地位相同),用于定义枚举类。枚举类是一个特殊的类,它一样可以有自己的成员变量、方法,可以实现一个或多个接口,也可以定义自己的构造器。一个java源文件最多只能定义一个public访问权限的枚举类,且该java源文件也必须和该枚举类的类名相同。

枚举和普通类的区别:

  • 枚举类可以实现一个或多个接口,使用enum定义的枚举类默认继承了java.lang.Enum类,而不是默认继承Object类,因此枚举类不能显式继承其他父类。其中java.lang.Enum类实现了java.lang.Serializablejava.lang.Comparable两个接口。
  • 使用enum定义、非抽象的枚举类默认会使用final修饰,因此枚举类不能派生子类。
  • 枚举类的构造器只能使用private访问控制器,如果省略了构造器的访问控制符,则默认使用private修饰;如果强制指定访问控制符,则只能指定private修饰符;
  • 枚举类的所有实例必须在枚举类的第一行显式列出,否则这个枚举类永远都不能产生实例。列出这些实例时,系统会自动添加public static final修饰,无须程序员显示添加;

枚举类入门:

public enum SeasonsEnum {
		// 使用构造器创建对象
    SPRING("春天"), SUMMER("夏天"), FALL("秋天"), WINTER("冬天");

    private final String name;
		// 枚举的构造器只能使用private修饰
    private SeasonsEnum(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

上面的程序中,在第一行中显式的列出枚举值,其中SPRING("春天")是调用构造器创建枚举类对象,只是这里无须new 关键字,也无须显示调用构造器。因为这里的构造器是含有参数的,所以必须传入一个参数;其实,SPRING("春天")实际上等同于下面的代码:

private static final SeasonsEnum SPRING = new SeasonsEnum("春天");

实现接口的枚举类

枚举类也可以实现一个或者多个接口,与普通实现一个或多个接口完全一样,枚举类实现一个或多个接口,也需要实现该接口所包含的方法。

// 枚举类接口
public interface EnumInterface {

    public void say();
}

// 实现接口的枚举类
public enum SeasonsEnum implements EnumInterface{

    SPRING("春天"), SUMMER("夏天"), FALL("秋天"), WINTER("冬天");

    private final String name;

    SeasonsEnum(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public void say() {
        System.out.println("枚举类");
    }
}

上面这种实现接口方式,SeasonsEnum.XXXX.say();最终的调用结果都是调用统一的say方法,所以如果想要每个枚举值调用不同发say()方法,就需要在枚举值后面加上花括号,例如:

public enum SeasonsEnum implements EnumInterface{

    SPRING("春天"){
        public void say(){
            System.out.println("我是春天");
        }
    }, SUMMER("夏天"){
        public void say(){
            System.out.println("我是夏天");
        }
    }, FALL("秋天"){
        public void say(){
            System.out.println("我是秋天");
        }
    }, WINTER("冬天"){
        public void say(){
            System.out.println("我是冬天");
        }
    };

    private final String name;

    SeasonsEnum(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

}

这样的话,调用SeasonsEnum.SPRING.say();输入的就是‘我是春天’ ;编译上面的文件会产生5个class文件,其实SeasonsEnum对应一个文件,它的4个匿名内部子类分别各对应一个class文件;

含抽象方法的枚举类

上面我们说过非抽象的枚举类默认使用final修饰。那么当枚举类中包含抽象方法,它就是抽象类,系统会默认使用abstract修饰,而不是final

public enum SeasonEnum {

    SPRING("春天"){
        public void say(){
            System.out.println("this is spring");
        }
    }, SUMMER("夏天"){
        public void say(){
            System.out.println("this is summer");
        }
    }, FALL("秋天"){
        public void say(){
            System.out.println("this is summer");
        }
    }, WINTER("冬天"){
        public void say(){
            System.out.println("this is winter");
        }
    };

    private final String name;

    SeasonEnum(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public abstract void say();
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值