• 《疯狂Java讲义》(十六)---- 枚举类


    •  枚举类与普通类的区别
      •  枚举类可以实现一个或多个接口,使用enum定义的枚举类默认继承java.lang.Enum类,而不是java.lang.Object类,其中java.lang.Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口。
      •    使用enum定义,非抽象的枚举类默认会使用final修饰,因此枚举类不能派生子类。
      •    枚举类的构造器只能使用private访问控制符
      •    枚举类的所有实例必须在枚举类的第一行显式列出,否则这个枚举类永远不能产生实例。列出这些实例时,系统会自动添加public static final修饰,无须程序员显式添加。
      •    枚举类都提供了一个values方法,该方法可以很方便地遍历所有的枚举值。
    enum SeasonEnum {
        SPRING, SUMMER, FALL, WINTER;
    }
    
    public class EnumTest {
    
        public void judge(SeasonEnum s) {
            switch (s) {
                case SPRING:
                    System.out.println("Spring is comming");
                    break;
                case SUMMER:
                    System.out.println("Summer is comming");
                    break;
                case FALL:
                    System.out.println("Fall is comming");
                    break;
                case WINTER:
                    System.out.println("Winter is comming");
                    break;
                default:
                    System.out.println("not exist season");
            }
        }
    
        public static void main(String[] args) {
            for (SeasonEnum s : SeasonEnum.values()) {
                System.out.println(s);
            }
    
            new EnumTest().judge(SeasonEnum.SPRING);
    
        }
    
    }
    • 枚举类的Field/方法/构造函数

        枚举类一样可以定义Field和方法。也可以将field访问符设置为public,直接修改值,但这样破坏了类的封装性。也可以将field访问符改为private,提供getter和setter,但是通常枚举类应该设计成不可变类。

        枚举类的field值不应该允许改变,这样会更安全,而且代码也简洁。所以,枚举类的field都使用private final修饰。所以必须在构造器里为这些Field指定初始值(或载定义field时指定默认值, 在初始化块中指定初始值,但这两种情况并不常见),因此应该为枚举类显式定义带参数的构造器。一旦为枚举类显式定义了带参数的构造器,在第一行列出枚举实例时就必须对应的传入参数。

    public enum Gender {
    
        MALE("nan"), FEMALE("nv");
        
        private final String name;
        
        private Gender(String name) {
            this.name = name;
        }
        
        public String getName() {
            return this.name;
        }
    }

      在枚举类中列出枚举值时,实际上就是调用构造器创建枚举类对象,只是这里无须使用new关键字,也无须显式调用构造器。上一个例子中列出枚举值时没有传入参数,仅仅是因为前面的枚举类包含无参数的构造器。

      MALE("nan") 相当于 public static final Gender MALE = new Gender("nan");

    • 实现接口的枚举类
    interface GenderDesc {
        void info();
    }
    public enum Gender2 implements GenderDesc{
        MALE, FEMALE;
    
        @Override
        public void info() {
            // TODO Auto-generated method stub
            
        }
    
    }

    如果由枚举类来实现接口里的方法,则每个枚举类在调用该方法时都有相同的行为方式。如果需要每个枚举值在调用该方法时呈现不同的行为方式,则可以让每个枚举值分别来实现该方法

    interface GenderDesc {
        void info();
    }
    public enum Gender2 implements GenderDesc{
        MALE {
    
            @Override
            public void info() {
                // TODO Auto-generated method stub
                
            }
        }, FEMALE {
            
            @Override
            public void info() {
                // TODO Auto-generated method stub
                
            }
        };
    
    }

    上边的情况中, 当创建MALE/FAMALE枚举值,并不是直接创建Gender枚举类的实例,而是相当于创建Gender的匿名子类的实例。

    编译上边程序,生成Gender.class, Gender$1.class, Gender$2.class三个文件,证明MALE和FEMALE实际上是Gender匿名子类的实例,而不是Gender类的实例。

    提问:枚举类不是用final修饰了吗?怎么还能派生子类呢?

    回答:并不是所有的枚举类都是用了final修饰符,非抽象的枚举类才默认是用final修饰。对于一个抽象的枚举类而言 -- 只要它包含了抽象方法,它就是抽象枚举类,系统会默认是用abstract修饰,而不是final。

    • 包含抽象方法的枚举类
    public enum Operation {
    
        PLUS {
            public double eval(double x, double y) {
                return x + y;
            }
        },
        MINUS {
            public double eval(double x, double y) {
                return x - y;
            }
        },
        TIMES {
            public double eval(double x, double y) {
                return x * y;
            }
        },
        DIVIDE {
            public double eval(double x, double y) {
                return x / y;
            }
        };
        public abstract double eval(double x, double y);
        
        public static void main(String[] args) {
            System.out.println(Operation.PLUS.eval(3, 4));
            System.out.println(Operation.MINUS.eval(3, 4));
            System.out.println(Operation.TIMES.eval(3, 4));
            System.out.println(Operation.DIVIDE.eval(3, 4));
        }
    }

     枚举类里定义抽象方法时不能使用abstract关键字将枚举类定义成抽象类(因为系统会自动为它添加abstract),但因为枚举类需要显式创建枚举值,而不是作为父类,所以定义每个枚举值时必须为抽象方法提供实现,否则编译错误。

  • 相关阅读:
    Windows Server 2003 IIS 使用 Excel.Application
    AutoCAD2008换硬盘后重新激活
    730KII 打印机 Win7 2017年11月更新系统补丁后无法打印
    军训卫生巾鞋垫尺码简易参考
    电阻功率与电流关系
    万用表判断场效应管的好坏
    避免电路接触时火花的产生
    phpexcel如何读和写大于26列的excel
    铅酸蓄电池正确使用与充电管理
    铅酸蓄电池单格最高与最低电压
  • 原文地址:https://www.cnblogs.com/IvySue/p/6343763.html
Copyright © 2020-2023  润新知