枚举类型

1、枚举类型的概念

先看一个例子。定义一个接口,这个接口用来定义常量:

public interface Common {

    public static final String YES = "yes";

    public static final String NO = "no";

    public static final int MIN_AGE = 18;

    public static final int MAX_AGE = 60;

}

测试:

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("请输入你的年龄:");
        int age = in.nextInt();
        if (age < Common.MIN_AGE || age > Common.MAX_AGE) {
            System.out.println("你这个年龄不适合谈恋爱!");
        } else if (age >= Common.MIN_AGE && age <= Common.MAX_AGE) {
            System.out.println("你恋爱成功了吗?输入yes或no");
            String bool = in.next();
            if (bool.equals(Common.YES)) {
                System.out.println("恭喜你,人生赢家!");
            } else if (bool.equals(Common.NO)) {
                System.out.println("加油,争取早日脱离光棍!");
            }
        }
    }

控制台:
在这里插入图片描述
在接触枚举类型之前,我们定义常量一般都会直接在类或接口中定义。枚举类型可以取代这种定义常量的方式,此外,枚举类型还提供了安全检查功能,本质上其实还是以类的形式存在的。Java枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一组交通信号灯的颜色等。

api文档说明如下:
在这里插入图片描述

2、枚举的定义

枚举类型的定义使用关键字enum,如下:

/*
 * 这个枚举类型中定义3种信号等颜色常量
 */
public enum Light {

    RED,
    YELLOW,
    GREEN;

}

RED、YELLOW、GREEN这三个是常量,之间用逗号隔开,最后一个后面是分号。如果引用枚举类型中的常量,比如Light.RED,这个其实是枚举类型的一个实例,这个要注意。以下测试:

    public static void main(String[] args) {
        List<Light> list = new ArrayList<>();
        Light current_light = null;
        // 可以看到,枚举类型中的每一个成员变量都是枚举类型的一个实例
        list.add(Light.RED);
        list.add(Light.GREEN);
        list.add(Light.YELLOW);
        System.out.println(Light.RED instanceof Light);
        Random ran = new Random();
        for (int i = 1; i <= 5; i++) {
            int res = ran.nextInt(3);
            // 信号灯随机跳转
            current_light = list.get(res);
            if (current_light.equals(Light.RED)) {
                System.out.println("现在是红灯,稍等一下!");
            } else if (current_light.equals(Light.YELLOW)) {
                System.out.println("现在是黄灯,应该视情况决定等待或行驶!");
            } else {
                System.out.println("现在是绿灯,可以放心通过!");
            }
        }
    }

执行,控制台:
在这里插入图片描述

3、枚举类的常用方法

api文档中的所有方法如下:
在这里插入图片描述
常用方法说明:

  • compareTo(E e):比较两个枚举对象在定义时的顺序,返回0、1、-1。
  • name():返回此枚举常量的名称,与其枚举声明中声明的完全相同。
  • ordinal():返回枚举成员的位置索引。(按照声明的位置,从0开始)
  • toString():返回声明中包含的此枚举常量的名称。
  • values():将枚举成员以数组的形式返回。
  • valuesOf():将普通字符串转为枚举实例。

代码中测试:

    public static void main(String[] args) {
        // 将字符串转换为枚举成员
        System.out.println(Light.valueOf("RED") == Light.RED);
        // 获取枚举成员的数组
        Light[] lights = Light.values();
        System.out.println("现在枚举类型中的成员数:" + lights.length);
        for (int i = 0; i < lights.length; i++) {
            System.out.println("枚举名称:" + lights[i].name() + "\t"
                               + "枚举值:" + lights[i].toString() + "\t"
                               + "所在位置索引:" + lights[i].ordinal() + "\t"
                               + "与YELLOW相比的位置:" + lights[i].compareTo(Light.YELLOW));
        }
    }

控制台:
在这里插入图片描述

4、类的内部定义枚举

在一个类的内部也可以定义枚举,像内部类那样:

public class Demo {

    // 类的内部定义枚举
    enum Letter {
        A,B,C,D;
    }

    // 自定义方法
    public static void t0(Letter letter) {
        switch (letter) {
        case A:
            System.out.println("t0方法======>A");
            break;
        case B:
            System.out.println("t0方法======>B");
            break;
        case C:
            System.out.println("t0方法======>C");
            break;
        case D:
            System.out.println("t0方法======>D");
            break;
        default:
            System.out.println("枚举中无此类型!");
            break;
        }
    }

    // 测试
    public static void main(String[] args) {
        Demo.t0(Letter.B);
    }

}

控制台:
在这里插入图片描述

5、枚举的属性、构造方法、实例方法

枚举跟普通类一样可以用自己的变量、方法和构造函数,构造函数只能使用private访问修饰符,所以外部无法调用。枚举既可以包含具体方法,也可以包含抽象方法。 如果枚举类具有抽象方法,则枚举类的每个实例都必须实现它。

以下通过例子说明。定义枚举类:

public enum Light {

    // 枚举成员
    RED,
    YELLOW,
    GREEN;

    // 成员属性
    private double height;// 信号灯的高度

    private int time;// 每种信号的持续时长

    // 构造方法修饰符要么不写,要么只能是private
    Light() {

    }

    private Light(double height, int time) {
        this.height = height;
        this.time = time;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public int getTime() {
        return time;
    }

    public void setTime(int time) {
        this.time = time;
    }
    
    //自定义方法
    public String workNormal() {
        return "信号灯工作正常!";
    }

}

测试:

    public static void main(String[] args) {
        Light[] lights = Light.values();
        // 为枚举实例初始化值
        lights[0].setHeight(2.5);
        lights[0].setTime(30);
        lights[1].setHeight(2.7);
        lights[1].setTime(50);
        lights[2].setHeight(3.0);
        lights[2].setTime(60);
        for (int i = 0; i < lights.length; i++) {
            System.out.println(lights[i].toString() + "灯高度为:" + lights[i].getHeight() 
                               + "米,持续" + lights[i].getTime() + "秒," + lights[i].workNormal());
        }
    }

控制台:
在这里插入图片描述

枚举类似普通的类,普通类中属性、方法等在枚举中也能定义,但是枚举的构造方法在外部是不能访问的。

6、枚举的常用用法

以前用枚举的时候,理解为枚举就只是用来定义常量的,后来发现,好像并不只是这样。参考了很多人的博客,了解到枚举常用用法有7种,在这里记录一下。

6.1、定义常量

这是最基本的用法,如下:

public enum Light {

    // 枚举成员
    RED,
    YELLOW,
    GREEN;
}

6.2、作为swicth的参数

上面其实用到过了,很早的时候switch只接受基本类型,后来可以支持枚举类型。如下:

public enum Light {

    // 枚举成员
    RED,
    YELLOW,
    GREEN;
}
public class Test {

    public static void main(String[] args) {
        Light light = Light.GREEN;
        switch (light) {
        case RED:
            System.out.println("现在是红灯,等一下吧!");
            break;
        case GREEN:
            System.out.println("现在是绿灯,可以放心行驶!");
            break;
        case YELLOW:
            System.out.println("现在是黄灯,没有车辆再过去吧!");
            break;
        default:
            System.out.println("交通灯坏了!");
            break;
        }
    }

}

在这里插入图片描述

6.3、枚举中定义实例方法

这种用法其实就是将枚举当做普通类一样,上面其实演示过了,添加新的方法:

public enum Light {

    // 枚举成员
    RED,
    YELLOW,
    GREEN;

    // 成员属性
    private double height;// 信号灯的高度

    private int time;// 每种信号的持续时长

    // 构造方法修饰符要么不写,要么只能是private
    Light() {

    }

    private Light(double height, int time) {
        this.height = height;
        this.time = time;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public int getTime() {
        return time;
    }

    public void setTime(int time) {
        this.time = time;
    }
    
    //自定义方法
    public String workNormal() {
        return "信号灯工作正常!";
    }

}

这里添加了一个workNormal()的成员方法。

    public static void main(String[] args) {
        Light[] lights = Light.values();
        // 为枚举实例初始化值
        lights[0].setHeight(2.5);
        lights[0].setTime(30);
        System.out.println(lights[0].toString() + "灯高度为:" + lights[0].getHeight() 
                + "米,持续" + lights[0].getTime() + "秒," + lights[0].workNormal());
    }

在这里插入图片描述

6.4、覆盖toString方法

其实可以看到,Enum类中只有一个toString方法能重写:
在这里插入图片描述
那么就像普通类覆盖toString方法就可以了:

public enum Light {

    // 枚举成员
    RED,
    YELLOW,
    GREEN;

    @Override
    public String toString() {
        return "这个toString方法是重写的!";
    }

}
    public static void main(String[] args) {
        System.out.println(Light.GREEN.toString());
    }

在这里插入图片描述

6.5、实现接口

这种用的比较多,比如开发中自定义错误代码、提示信息等。

接口如下:

public interface ResultCode {
    
    //返回是否操作成功
    boolean success();
    
    //返回操作代码
    int code();
    
    //返回提示信息
    String message();

枚举如下:

/*
 * 这个枚举实现接口
 */
public enum CommonCode implements ResultCode {

    USERNAME_IS_NULL(false, 10000, "登录名为空!"),
    PASSWORD_IS_NULL(false, 10001, "登录密码为空!"),
    USERNAME_IS_ERROR(false, 10002, "登录名错误!"),
    PASSWORD_IS_ERROR(false, 10003, "登录密码错误!"),
    LOGIN_SUCCESS(true, 10004, "登录成功!");

    // 成员属性
    boolean success;
    int code;
    String message;

    // 枚举的构造方法
    private CommonCode(boolean success, int code, String message) {
        this.success = success;
        this.code = code;
        this.message = message;
    }

    public boolean getSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public boolean success() {
        return success;
    }

    @Override
    public int code() {
        return code;
    }

    @Override
    public String message() {
        return message;
    }

    @Override
    public String toString() {
        return "{" + "\n" 
                + "\"success\"" + ":" + this.getSuccess() + "," + "\n"
                + "\"code\"" + ":" + this.getCode() + "," + "\n"
                + "\"message\"" + ":" + this.getMessage() + "\n"
                + "}";
    }

}

测试:

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("请输入登录名:");
        String username = in.next();
        if (username.equals("")) {
            System.out.println(CommonCode.USERNAME_IS_NULL);
            System.exit(0);
        }
        if (!username.equals("ycz")) {
            System.out.println(CommonCode.USERNAME_IS_ERROR);
            System.exit(0);
        }
        System.out.println("请输入登录密码:");
        String password = in.next();
        if (password.equals("")) {
            System.out.println(CommonCode.PASSWORD_IS_NULL);
            System.exit(0);
        }
        if (!password.equals("ycz123456")) {
            System.out.println(CommonCode.PASSWORD_IS_ERROR);
            System.exit(0);
        }
        if (username.equals("ycz") && password.equals("ycz123456")) {
            System.out.println(CommonCode.LOGIN_SUCCESS);
        }
    }

控制台:
在这里插入图片描述
再执行,然后输入正确的登录名,错误的密码:
在这里插入图片描述
再执行,然后输入正确的登录名,正确的密码:
在这里插入图片描述
这种枚举实现接口的形式,用的挺多,应该要重点掌握。

6.6、接口来组织枚举

在接口中可定义多个枚举,并且实现该接口。如下:

public interface UnionEnums {
    
    enum E0 implements UnionEnums{
        A,B,C,D,E;
    }
    
    enum E2 implements UnionEnums{
        F,G;
    }
    
    enum E3 implements UnionEnums{
        H,I,J,K;
    }  
}

6.7、枚举集合

很少使用,略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值