zoukankan      html  css  js  c++  java
  • 枚举类

     在某些情况下,有些类的对象是有限和固定的比如季节类,它只有4个对象,再比如行星类,只有8个对象。这种实例有限而且固定的类,在Java里被称为枚举类。在一个Java源文件中,最多只能定义一个public访问权限的枚举类,且该源文件也必须和该枚举类的类名相同

    一. 枚举类入门

    java 5新增了一个enum关键字(相当于class,interface)来定义枚举类。枚举类是一种特殊的类与普通类有些简单区别。

    • 枚举类可以实现一个或多个接口,使用enum定义的枚举类默认继承了java.lang.Enum类,而不是继承Object类,因此枚举类不能显式继承其他父类。其中java.lang.Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口。
    • 使用enum定义,非抽象的枚举类默认会使用final修饰,因此枚举类不能派生子类
    • 枚举类的构造器只能使用private访问控制符 ,默认使用private控制符,可省略不写
    • 枚举类的所有实例必须在枚举类的第一行显式指出,否则这个枚举类永远都不能产生实例。列出这些实例时,系统会自动添加public static final修饰无需程序显式添加
    • 枚举类默认提供了一个value()方法,该方法可以很方便的遍历所有的枚举值

    下面定义了一个SesssionEnum枚举类

    public enum SeasonEnum
    {
    SPRING,SUMMER,FALL,WINTER;
    
    }

    如果需要使用该枚举类的某个实例,则可使用Enumclass.variable的形式,如SessionEnum.SPRING。

    package com.gdut.enumTest;
    
    public class EnumTest {
        public void judge(SeasonEnum s) {
    //jdk1.5增加了swich表达式的拓展,表达式可以是任何枚举类型
    switch (s) { case SPRING:System.out.println("春暖花开,正好踏青"); break; case SUMMER:System.out.println("夏日炎炎,适合游泳"); break; case FALL:System.out.println("秋高气爽,进补及时"); break; case WINTER:System.out.println("大雪飘飘,围炉赏雪"); break; } } public static void main(String[] args) { for(SeasonEnum s : SeasonEnum.values()) { System.out.println(s); } //使用枚举类实例时,可通过EnumClass.variable形式来访问 new EnumTest().judge(SeasonEnum.SPRING); } }

    所有枚举类都继承了java.lang.Enum类,所以枚举类都可以使用java.lang.Enum的方法

    • int compareTo(E o):该方法用于指定枚举对象比较顺序,同一个枚举实例只能与相同类型的枚举实例进行比较。如果该枚举对象在指定枚举对象之后,则返回正整数;如果该枚举对象在指定枚举对象之前,则返回负整数;否则返回0。
    • String name:返回枚举实例名称,与toString()方法作用相当。
    • int ordinal():返回枚举值在枚举类中的索引值。
    • String toString():返回枚举实例名称,比name方法更常用
    • public static <T extends Enum<T>> T valueOf(Class<T> enumType,String name):返回指定枚举类中指定名称的枚举值

    上面程序打印的时候实际上调用了toString()方法,输出枚举值的名字

    二. 枚举类的成员变量,方法,构造器

    枚举类也是以种类,是一种特殊的类,它一样可以定义成员变量、方法和构造器。

    package com.gdut.enumTest;
    
    public enum Gender {
        MALE,FEMALE;
        public String name;
    }
    package com.gdut.enumTest;
    
    public class GenderTesst {
    
        public static void main(String[] args) {
            Gender g = Enum.valueOf(Gender.class, "FEMALE");
            g.name = "女";
            System.out.println(g+"代表:"+g.name);
        }
    
    }

    上面程序使用枚举类时与使用一个普通类没有太大差别,只是产生Gender对象的方式不同。枚举类的实例只能是枚举值,而不是随意通过new来创建枚举类对象。

    下面程序通过方法来控制对name的访问

    package com.gdut.enumTest;
    
    import java.util.IllegalFormatCodePointException;
    
    public enum Gender {
        MALE,FEMALE;
        private String name;
        
        public void setName(String name) {
            switch (this) {
            case MALE:
                if(name.equals("男")) this.name = name;
                else System.out.println("参数错误");
                break;
            case FEMALE:
                if(name.equals("女")) this.name = name;
                else System.out.println("参数错误");
                break;
                
      
            default:
                break;
            }
        }
    }

    实际上这种做法依然不够好,枚举类通常应该设计为不可变类,也就是说,他的变量值不应该允许改变,这样会更安全。因此建议枚举类的成员变量使用private final修饰。

    如果所有的成员变量都是用final修饰,则必须在构造器里为这些成员变量指定初始值(或者再定义时或初始块中指定,但这两种情况不常见),因此应该为枚举类显式指定带参数的构造器。

    package com.gdut.enumTest;
    
    public enum Gender {
        MALE("男"),FEMALE("女");
        private String name;
        
        private Gender(String name) {
            this.name = name;
        }
        
        public String getName() {
            return name;
        }
    }

    三. 实现接口的枚举类

    如果由枚举类实现接口里的方法,则每个枚举值在调用该方法时都有相同的行为方式(因为方法体完全一样)。如果需要每个枚举值在调用该方法时呈现不同的行为方式,则可让每个枚举值

    分别实现该方法。

    package com.gdut.enumTest;
    
    interface GenderDesc{
        void info();
    }
    
    public enum Gender implements GenderDesc{
        MALE("男"){
            @Override
            public void info() {
                System.out.println("这个枚举值代表男性");
            }
            
        },FEMALE("女"){
            @Override
            public void info() {
                System.out.println("这个枚举值代表男女性");
            }
            
        };
        
        private String name;
        
        private Gender(String name) {
            this.name = name;
        }
        
        public String getName() {
            return name;
        }
    
        
    }

    便宜上面的程序,可看到生成Gender.class,Gender$1.class,Gender$2.class三个文件,证明了MALE和FEMALE实际上是Gender类的匿名子类的实例,而不是Gender类的实例。                                   四. 包含抽象方法的枚举类

    假设一个枚举类Operation包含四个实例:PLUS,MINUS,TIMES,DIVIDE分别代表加减乘除4种运算,该枚举类需要定义一个eval()抽象方法来完成计算。

    package com.gdut.enumTest;
    
    public enum Operation {
    PLUS(){
        @Override
        public double eval(double num1, double num2) {
            return num1+num2;
        }
        
    },MINUS(){
        @Override
        public double eval(double num1, double num2) {
            return num1-num2;
        }
        
    },TIMES {
        @Override
        public double eval(double num1, double num2) {
            return num1*num2;
        }
    },DIVIDE {
        @Override
        public double eval(double num1, double num2) {
            return num1/num2;
        }
    };
        private Operation() {
        }
        public abstract double eval(double num1,double num2);
        
        public static void main(String[] args) {
            System.out.println(Operation.PLUS.eval(5,3));
            System.out.println(Operation.MINUS.eval(5, 3));
            System.out.println(Operation.TIMES.eval(5,3));
            System.out.println(Operation.DIVIDE.eval(5,3));
        }
        
    }
  • 相关阅读:
    Entity Framework Code First 模式-建立一对一联系
    Entity Framework Code First 模式-建立一对多联系
    sqllocaldb
    NuGet 命令行使用EntityFrameWork
    c# 中反射里的invoke方法的参数
    在js中使用Razor
    一个页面上调用多个setInterval失效解决办法(使用于同一时间间隔)
    Echart使用过的属性总结
    VS注释与取消注释快捷键
    hibernate的强转类型
  • 原文地址:https://www.cnblogs.com/yumiaoxia/p/9021941.html
Copyright © 2011-2022 走看看