Enum 枚举

JDK1.5增加了枚举类型,可以使用enum来定义。

例如:
    public enum Gender{
        MALE,FEMALE;
    }

其中每一个枚举元素都是该枚举类型的一个实例,并且默认是用public static final修饰的。

※枚举类构造器及方法

Enum 枚举_第1张图片

※ 枚举类型和类的关系

把Gender.class反编译后显示如下:

          public final class com.briup.test.Gender extends java.lang.Enum<com.briup.test.Gender> {
          public static final com.briup.test.Gender MALE;
          public static final com.briup.test.Gender FEMALE;
          private static final com.briup.test.Gender[] ENUM$VALUES;
          static {};
          private com.briup.test.Gender(java.lang.String, int);
          public static com.briup.test.Gender[] values();
          public static com.briup.test.Gender valueOf(java.lang.String);
        }

说明枚举类型本质还是一个类,而且默认就是fianl修饰以及默认继承父类java.lang.Enum。
同时构造器是自动生成的且是私有的,表示不可再创建对象。(使用反射也不行)
private Gender(String name,int ordinal)
name : 枚举对象的名字
ordinal: 枚举元素的编号,默认从0开始

我们在枚举中所写的MALE和FEMALE其实就是Gender类型的俩个固定的对象。(public static final)

注:enum是java中的一个关键字,Enum是java中的一个类

※ 获取枚举对象

1.获得枚举对象(三种方式)
枚举对象在我们使用之前就已经全部创建好了,并且不会增加或减少,和声明的时候保持一致。

例如:
            Gender g1 = Gender.FEMALE;
            Gender g2 = Gender.MALE;

            Gender g3 = Gender.valueOf("FEMALE");
            Gender g4 = Gender.valueOf("MALE");

            System.out.println(g1 == g3);//true
            System.out.println(g2 == g4);//true

            Gender g5 = Enum.valueOf(Gender.class, "FEMALE");
            Gender g6 = Enum.valueOf(Gender.class, "MALE");
            System.out.println(g1 == g5);//true
            System.out.println(g2 == g6);//true

2.获得一个枚举类型的所有对象

Gender[] values = Gender.values();
            for(Gender g:values){
                System.out.println(g);
            }

※ 枚举类型的方法

枚举对象默认只能调用到父类Enum中的方法以及Object中的方法

如果想调用自己的方法,也可以在枚举类型中定义出属于自己的方法.
注:枚举也是类,只是一种特殊的类而且,所以在枚举类型中可以定义很多东西,像之前在类中写代码是一样的

例如:
        public enum Gender {
            MALE,FEMALE;

            public void say(String name){
                System.out.println("hello "+name+","+this);
            }
            public static void main(String[] args) {
                Gender g1 = Gender.FEMALE;
                Gender g2 = Gender.MALE;

                g1.say("tom");
                g2.say("tom");
            }
        }

也可以定义静态方法

例如:
        public enum Gender {
            MALE,FEMALE;

            public void say(String name){
                System.out.println("hello "+name+","+this);
            }
            public static void run(){
                System.out.println("running..");
            }
            public static void main(String[] args) {
                Gender.run();
            }
        }

※ 枚举类型的属性

枚举类型中可以定义属于自己的属性。

例如:
        public enum Gender {
            MALE,FEMALE;

            private String name;

            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
            //重写toString方法
            public String toString() {
                return this.getName();
            }
            public static void main(String[] args) {
                Gender g = Gender.FEMALE;
                g.setName("女");
                System.out.println(g);
            }
        }

※ 枚举类型的构造器

在枚举类型中定义其构造器,但是必须是私有的,默认也是私有的。

例如:
        public enum Gender {
            //默认调用无参构造器
            MALE,FEMALE;

            private String name;

            //有参构造器
            private Gender(String name){
                this.name = name;
            }
            //无参构造器
            Gender(){

            }

            //重写toString方法
            public String toString() {
                return this.name;
            }
        }

※ 构造器的调用:
在声明枚举对象的时候,其实就是在调用构造器,默认是隐式调用其无参构造器,也可以显式调用有参构造器。

例如:
        public enum Gender {
            MALE("男"),FEMALE("女");

            private String name;
            private Gender(String name){
                this.name = name;
            }
            Gender(){
                this("");
            }
            public String toString() {
                return this.name;
            }
            public static void main(String[] args) {
                Gender g = Gender.FEMALE;
                System.out.println(g);
            }
        }

※ 枚举类型的抽象方法

枚举类型中可以编写抽象方法,但是这时候其每个对象都必须去实现这个抽象方法,否则编译报错。

形式上很像匿名内部类对象
        例如:
        public enum Gender {
            MALE(){
                public void run() {
                    System.out.println("MALE run");
                }
            },FEMALE(){
                public void run() {
                    System.out.println("FEMALE run");
                }
            };

            public abstract void run();
        }

※ 枚举类型可以实现接口

枚举类型不能指定继承其他父类,但是可以实现其他接口。

例如:枚举类型中把该接口中的所有方法实现了
        public interface Action{
            void doSomeThing();
        }

        public enum Gender implements Action{
            MALE,FEMALE;

            public void doSomeThing() {
                System.out.println("Gender go..");
            }
        }

        例如:或者在每个对象中分别实现接口中所有方法也可以
        public interface Action{
            void doSomeThing();
        }
        public enum Gender implements Action{
            MALE(){
                public void doSomeThing() {
                    System.out.println("MALE go...");
                }
            },FEMALE(){
                public void doSomeThing() {
                    System.out.println("FEMALE go...");
                }
            };
        }

※ 枚举类实例

package com.briup.Enum;
/*
 * 在表示某些特定范围值的时候声明枚举
 * 性别(男,女) ,星期(星期1~星期天),扑克牌
 * 枚举类是一个特殊的普通类
 * 枚举不能有子类,也不能有父类(编译成.class 的时候
 * 编译器会给枚举类extends Enum)
 */
public enum Gender {
    //枚举变量必须放在枚举类中的第一行
    //每一个枚举变量都是单前枚举类的实列对象
    //枚举变量定义的时候有角标,定义多个枚举变量
    //中间逗号隔开,最后分号表示枚举申明结束
    MALE,FEMALE("lisi");
    //枚举变量后面可以写静态和非静态的变量及方法
    //非静态的使用先获取枚举对象,在使用
    //静态的枚举类.属性 枚举类.方法名直接使用
    private String name;
    public static int age=30;
    //枚举类型的构造器只能是私有的,不能new对象
    //反射也不能使用该构造器构建对象,
    private Gender() {
        //this调用构造器必须至于第一行
        this("tom");
        //System.out.println("11111");
    }
    private Gender(String name){
        //super调用父类构造器不行
        this.name=name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

package com.briup.Enum;
/*
 * 实现接口之后,重写方法
 * 1,在枚举变量的外部重写方法,方法重写了和枚举变量同级
 * 两个枚举共享该方法
 * 2.在每一个枚举变量的内部都重写方法,属于枚举变量
 * 自身的方法
 */
public  enum Gender1 implements UserService{
    FEMALE {
        @Override
        public void say() {
            // TODO Auto-generated method stub
            System.out.println("test.....");
        }

        @Override
        public void addUser() {
            // TODO Auto-generated method stub
            System.out.println("female....s");
        }
    },MALE {
        @Override
        public void say() {
            // TODO Auto-generated method stub
            System.out.println("^^^^^........");
        }

        @Override
        public void addUser() {
            // TODO Auto-generated method stub
            System.out.println("male.....");
        }
    };
    /*
     * 枚举类中可以定义抽象的方法,一旦有抽象的
     * 方法必须在枚举变量中重写,重写之后的方法各自属于各自
     * 的枚举变量
     * 
     */
    public abstract void say();
//  public void addUser(){
//      System.out.println("addUser......");
//  }
}

interface UserService{
    void addUser();
}





package com.briup.Enum;

public enum Gender2 {
    MALE{
        //内部自定义的属性和方法,外部没有,不能调用,只能
        //内部使用
        private String name="toms";
        public String getName(){
            return name;
        }
        public void setName(String name){
            this.name=name;
        }
        //枚举变量外部已经有一个方法,内部写一个一摸一样的
        //方法,重写覆盖外部的方法
        public void say(){
            System.out.println("h.....");
        }

    },FEMALE;
    private String name="lisi";
    {}
    static{}
    public void say(){
        System.out.println("say.....");
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}



package com.briup.Enum;

public class Test {
    public void test(){
        //第一种
        Gender g=Gender.MALE;
        Gender g1=Gender.FEMALE;
//      System.out.println(g+"--"+g1);
        //第二种获取方式
        Gender g2=Gender.valueOf("MALE");
//      System.out.println(g2);
        //第三种方法
        Gender[] g3=Gender.values();
//      for(Gender gg:g3){
//          System.out.println(gg);
//      }
        //第四种方式,第一个参数枚举的镜像,第二个参数枚举变
        //量的名字
        Gender g5=Enum.valueOf(Gender.class, "FEMALE");
        System.out.println(g5);
    }
    public void test1(){
        Gender g=Gender.FEMALE;
        System.out.println(g.name());//获取枚举变量的名字
        System.out.println(g.ordinal());//获取枚举变量所处的位置
        Class c=g.getDeclaringClass();//获取枚举类的镜像
        Class c1=Gender.class;
        System.out.println(c==c1);//true
    }
    public void test2(){
        //Gender g=Gender.FEMALE;
        Gender g1=Gender.MALE;
        String name=g1.getName();
        System.out.println(name);
    }
    public static void main(String[] args) {
        new Test().test2();
    }
}

你可能感兴趣的:(Java基础知识)