面向对象进阶之枚举

57 阅读4分钟

1. 认识枚举

枚举是一种特殊的类,它的格式是:

public enum 枚举类名{
    枚举项1,枚举项2,枚举项3;
    其他成员……
}

其实枚举项就表示枚举类的对象,只是这些对象在定义枚举类时就预先写好了,以后就只能用这几个固定的对象。

我们用代码演示一下,定义一个枚举类A,在枚举类中定义三个枚举项X, Y, Z

public enum A{
    X,Y,Z;
}

注意:

  • 枚举类中的第一行,只能写一些合法的标识符(名称),多个名称用逗号隔开。
  • 这些名称,本质是常量,每个常量都会记住枚举类的一个对象。

想要获取枚举类中的枚举项,只需要用类名调用就可以了

public class Test{
    public static void main(String[] args){
        //获取枚举A类的,枚举项
        A a1 = A.X;
        A a2 = A.Y;
        A a3 = A.Z;
    }
}

枚举项实际上是枚举类的对象,这一点其实可以通过反编译的形式来验证(需要用到反编译的命令,这里不能直接将字节码拖进idea反编译,需要用到javac编译.java文件,再用javap进行反编译)

public final class A extends java.lang.Enum<A> {
    public static final A X = new A();
    public static final A Y = new A();
    public static final A Z = new A();
        
    public static A[] values();
    public static A valueOf(java.lang.String);
 }

我们会看到,枚举类A是用class定义的,说明枚举确实是一个类,被final修饰,所以枚举类A是不可被继承的。而且X,Y,Z都是A类的对象;而且每一个枚举项都是被public static final修饰,是常量,所以被可以类名调用,而且不能更改。

枚举类的特点

  • 枚举类的第一行只能罗列一些名称,这些名称都是常量,并且每个常量记住的都是枚举类的一个对象。
  • 枚举类的构造器都是私有的(写不写都只能是私有的),因此,枚举类对外不能创建对象。
  • 枚举都是最终类,不可以被继承。
  • 枚举类中,从第二行开始,可以定义类的其他各种成员。
  • 编译器为枚举类新增了几个方法,并且枚举类都是继承:java.lang.Enum类的,从enum类也会继承到一些方法

多学一招: 可以通过枚举类实现单例设计模式(在枚举类中只写一个枚举项)

枚举类深入

枚举是一个类,可以在枚举类中定义构造器、成员变量、成员方法,但是不推荐可以用普通类来实现

public enum A{
    //定义枚举项
    X,Y,Z("张三"); //枚举项后面加括号,就是在执行枚举类的带参数构造方法。
    
    //定义空构造器
    public A(){
        
    }
    
    //成员变量
    private String name;
    //定义带参数构造器
    public A(String name){
        this.name=name;
    }
    
    //成员方法
    public String getName(){
        return name;
    }
    ...
}

2.枚举类应用场景

枚举一般表示一组信息,然后作为参数进行传输。
        我们来看一个案例。比如我们现在有这么一个应用,用户进入应用时,需要让用户选择是女生、还是男生,然后系统会根据用户选择的是男生,还是女生推荐不同的信息给用户观看。(一般开发中,用0表示男生,1表示女生)
        这里我们就可以先定义一个枚举类,用来表示男生、或者女生

public class Constant{
    BOY,GRIL
}

再定义一个测试类,完成用户进入系统后的选择

public class Test{
    public static void main(String[] args){
        //调用方法,传递男生
        provideInfo(Constant.BOY);
        //调用方法,传递女生
        provideInfo(Constant.GIRL);
    }
    
    public static void provideInfo(Constant c){
        switch(c){
            case BOY:
                System.out.println("展示一些信息给男生看");
                break;
            case GRIL:
                System.out.println("展示一些信息给女生看");
                break;
        }
    }
}

这样可以让开发者及代码阅读者很清晰的知道需要传入的参数是什么,传入的参数对应的是男生还是女生,以及规避了用int型形参接受数据时,非0非1的变量值。