对枚举类的总结

胡泽宇 2020年02月08日 65次浏览

枚举

枚举是一个实例数量已经固定的类。
推论:枚举很方便地实现单例模式(Singleton)

语法格式

[public] (隐式的 abstract或final) enum 枚举名
{
    //第一行列举出所有实例,枚举以后只能用这些实例。
    //同样可以定义类的5大成员(成员变量、方法、构造器、初始化块、内部类)
}

与普通类的语法区别:

  • 枚举默认已经继承了Enum类(Object的子类z),因此枚举不能继承其他类。
  • 枚举类默认要么是final类,要么是抽象类。
    • 如果枚举类没有抽象方法,系统自动添加final。如果添加了抽象方法,系统自动添加abstract(不允许显式添加final和abstract)。
  • 枚举类的构造器只能用private修饰,如果不写系统自动添加private
  • 枚举要求在第一行列出所有实例
定义一个最简单的枚举类:

1

定义枚举之后,枚举默认自动拥有如下方法:

  • static 枚举类名[] values(); //该方法返回所有的枚举实例
  • static Season valueOf(String name); //该方法根据枚举名返回枚举实例
  • String name(); //该方法返回枚举实例的名字
  • int ordinal(); //该方法返回枚举实例的序号

枚举可用于:

  1. 定义变量
  2. 调用类方法或者类变量
测试一下将才上面描述枚举的方法:

2

输出结果:

3
枚举还可以配合switch使用:

switch表达式可以是: byte、short、int、String(Java7)、枚举enum

4

枚举与构造器:

枚举的第一行,并不是简单地列出枚举实例
第一行实际要创建、并列出枚举类的所有实例,因此需要根据构造器来传入对于的参数。
  • 案例:
    • 创建了一个枚举类,并定义了一个成员变量,和一个有参构造器:
      5
    • 发现第一行定义的四个枚举类都调用不了无参构造器,原因是因为没有定义。现在加上无参构造器:
      6
    • 定义成功,其中EAST和WEST调用了有参构造器进行实例化,SOUTH和NORTH调用了无参构造器进行实例化。来测试一下:
      7
      8

结果是对的,通过调有参枚举实例 desc 有值,通过调用无参的构造器的枚举实例 desc的值为null

抽象枚举

一般人的观点是,抽象类有个特点,不能创建实例。
枚举要在第一行列举并创建所有的实例。
这不是互相矛盾吗,枚举不能是抽象的。

我才开始也觉得上面的话很有道理,看了一些书之后发现是有抽象枚举这个概念的。
每个枚举实例都需要用匿名内部类来实现抽象枚举类中所有的抽象方法就可以了.

用官方一点的话来说:

枚举是可以抽象的,只要你为枚举定义了抽象方法,系统会自动为该枚举添加abstract修饰。
如果枚举是抽象的,那就需要在第一行用匿名内部类语法去创建枚举实例.

  • 抽象枚举案例:
    • 我先创建了一个带abstract方法的枚举类:
      9
      通过使用匿名内部类,把所有实例都创建好。
    • 结合匿名内部类的语法进一步扩展:
      10

枚举实现接口

枚举可以实现接口。

  • 枚举实现接口,必须实现接口中所有抽象方法,这就是一个普通枚举。
  • 枚举实现接口,但并不是实现接口中所有抽象方法,此时就变成了一个抽象枚举类
    需要在第一行用匿名内部类的语法去创建枚举实例(和上面抽象枚举一样)。
    今天总结了两篇博客手有点累了,实例其实跟上面的抽象枚举案例差不多,就是先定义一个接口,再定义一个枚举类实现它。两个情况,第一种直接在枚举类里面实现所有的抽象方法,然后就是一个普通的枚举类。第二种,不把所有抽象方法实现完,或者根本不实现,这个枚举类就变成了抽象枚举类,解决方案和上面一样。