• 进阶JAVA篇-深入了解枚举与抽象枚举


    目录

          介绍一下枚举:

              1.1枚举的概念

              1.2具体如何来使用呢?

              1.3对枚举小结

              1.4抽象枚举概念

              1.5对抽象枚举小结


                    介绍一下枚举:

            1.1枚举的概念

            在JAVA中,枚举是一种特殊的类,用于定义一组常量。Java中的枚举类型是通过使用关键字"enum"来定义的。枚举类中的第一行只能写一些合法的标识符(名称),多个名称需要逗号相隔开来,这些名称本质是常量,每个常量都会记住一个枚举类的对象。枚举类里面除了第一行的常量之外,其余跟一般的类所具有的成员(变量、方法、构造器、代码块、内部类)都有具有。

    代码如下:

    1. public class Text {
    2. public static void main(String[] args) {
    3. }
    4. }
    5. enum EnumerateClasses{
    6. X,Y,Z;
    7. private String name;
    8. private int age;
    9. public void fun(){
    10. System.out.println("调用枚举类中的方法");
    11. }
    12. EnumerateClasses() {
    13. }
    14. EnumerateClasses(String name, int age) {
    15. this.name = name;
    16. this.age = age;
    17. }
    18. public String getName() {
    19. return name;
    20. }
    21. public void setName(String name) {
    22. this.name = name;
    23. }
    24. public int getAge() {
    25. return age;
    26. }
    27. public void setAge(int age) {
    28. this.age = age;
    29. }
    30. }

             接下来我们反汇编来观察枚举类,深入枚举内部了解一下:

            

            先来看第一个“红框”用关键字final来修饰一个枚举类,所以枚举类是不可以被别的类所继承的,枚举类是最终类。再来看第二个“大红框”,编写的第一行的符号(名称),之所以被称为常量,这样就一清二楚了,是因为用static final 来修饰所编写的名称,还有一个要注意的是,这些名称的类型是一个类!!!因此可以这样说枚举类的第一行必须罗列的是枚举对象的名称。

            还有一点注意,通过反汇编观察到,枚举类中无论是无参构造器还是有参构造器中都默认为私有的(private)来修饰构造器,所以枚举是不可以在枚举外部new创建对象的,只能在内部。其实枚举就是一个只能在自己内部定义自己的对象。

    如下:

             1.2具体如何来使用呢?

    代码如下:

    1. public class Enum {
    2. public static void main(String[] args) {
    3. EnumerateClasses enumerateClasses = EnumerateClasses.X;
    4. enumerateClasses.fun();
    5. System.out.println(enumerateClasses.getName());
    6. System.out.println(enumerateClasses.getAge());
    7. }
    8. }
    9. enum EnumerateClasses{
    10. X("lisi",12),Y,Z;
    11. private String name;
    12. private int age;
    13. public void fun(){
    14. System.out.println("调用枚举类中的方法");
    15. }
    16. EnumerateClasses() {
    17. }
    18. EnumerateClasses(String name, int age) {
    19. this.name = name;
    20. this.age = age;
    21. }
    22. public String getName() {
    23. return name;
    24. }
    25. public void setName(String name) {
    26. this.name = name;
    27. }
    28. public int getAge() {
    29. return age;
    30. }
    31. public void setAge(int age) {
    32. this.age = age;
    33. }
    34. }

            对以上代码进行分析,首先先在枚举内初始化 X("lisi","12") 这个方式就是在用私有的有参数的构造器创建对象,因为这个对象是用static final修饰的,该对象将成为类的静态常量,所以可以用枚举名.对象,然后用枚举类型的变量来接收,接着就可以用这个变量名去访问公开的成员了。

     编译器中为枚举新增加了几个方法,下面来展示一下:

    1. public class Enum {
    2. public static void main(String[] args) {
    3. EnumerateClasses enumerateClasses = EnumerateClasses.X;
    4. enumerateClasses.fun();
    5. System.out.println(enumerateClasses.getName());
    6. System.out.println(enumerateClasses.getAge());
    7. //该方法可以得到全部对象,并且放到一个数组中
    8. EnumerateClasses[] e = EnumerateClasses.values();
    9. for (int i = 0; i < e.length; i++) {
    10. EnumerateClasses j = e[i];
    11. System.out.print(j.getName()+" ");
    12. System.out.println(j.getAge());
    13. }
    14. System.out.println("-----------------------------------------");
    15. //该方法可以得到指定的对象
    16. EnumerateClasses name = EnumerateClasses.valueOf("X");
    17. System.out.print(name.getName() + " ");
    18. System.out.println(name.getAge());
    19. //该方法可以得到该对象对应的索引
    20. System.out.println(name.ordinal());
    21. }
    22. }
    23. enum EnumerateClasses{
    24. X("李四",12),Y("王五",22),Z("张三",33);
    25. private String name;
    26. private int age;
    27. public void fun(){
    28. System.out.println("调用枚举类中的方法");
    29. }
    30. EnumerateClasses() {
    31. }
    32. EnumerateClasses(String name, int age) {
    33. this.name = name;
    34. this.age = age;
    35. }
    36. public String getName() {
    37. return name;
    38. }
    39. public void setName(String name) {
    40. this.name = name;
    41. }
    42. public int getAge() {
    43. return age;
    44. }
    45. public void setAge(int age) {
    46. this.age = age;
    47. }
    48. }

            1.3对枚举小结:

            第一行定义的是常量,用合法字符来表示,每一个字符都会对应一个对象,该对象是类的静态常量,可以直接被类访问。枚举不能被继承,也不能去new对象,只能在枚举内部创建对象。了解了三个编译器为枚举新增的方法,分别可以得到全部对象,可以得到指定的对象,可以查找该对象的索引。

            1.4抽象枚举概念

            抽象枚举相比与普通的枚举,就是在枚举内部有抽象方法,需要重写抽象方法,才能够在枚举里面创建对象。

    代码如下:

    1. public class Text {
    2. public static void main(String[] args) {
    3. E e1 = E.CAT;
    4. E e2 = E.DOG;
    5. e1.go();
    6. e2.go();
    7. }
    8. }
    9. enum E {
    10. CAT("小猫"){
    11. @Override
    12. public void go() {
    13. System.out.println(getName()+"优雅地走");
    14. }
    15. },DOG("傻狗"){
    16. @Override
    17. public void go() {
    18. System.out.println(getName()+"狂跑");
    19. }
    20. };
    21. private String name;
    22. public abstract void go();
    23. E(String name) {
    24. this.name = name;
    25. }
    26. public String getName() {
    27. return name;
    28. }
    29. public void setName(String name) {
    30. this.name = name;
    31. }
    32. }

            对以上代码简单分析一下,首先枚举里面有一个有参数的构造器,只能用这个构造器来创建对象了,发现枚举里面还有一个抽象方法,如果没有重写这个方法是不能创建对象的,所以在创建对象的时候需要重写方法,这个方式跟匿名内部类很相识的,需要区别开来。重写完方法后,就可以创建对象了,用E的类型变量去接收这些对象。

    反编译观察CAT这个类:

           1.5对抽象枚举小结

            枚举如果有定义抽象方法的话,这个就是抽象枚举了。如果这时候创建对象的时候没有去抽象方法进行重写,创建对象就会失败。



  • 相关阅读:
    Day10:寻路算法值之A*寻路算法
    基于PHP+MySQL动漫周边商城销售网站的开发与设计
    python树结构包treelib入门及其计算应用
    Python: 使用pytest进行代码测试
    计算机网络 | 应用层
    神领物流 day02-网关与支付 Spring Cloud Alibaba 微服务
    C++之《连连看》
    0085 查找算法
    学习Java的第十一天
    一周速学SQL Server(第六天)
  • 原文地址:https://blog.csdn.net/Tingfeng__/article/details/133746480