枚举类

枚举类

1、手动实现枚举类

public class SeasonDemo {
    public  static final  int SEASON_SPRING=1;
    public  static final  int SEASON_SUMMER=2;
    public  static final  int SEASON_FAIL=3;
    public  static final  int SEASON_WINTER=4;
}

缺点:
- 类型不安全:每一个季节的值均为int类型,季节可以被当做整数使用。
- 没有命名空间:当需要使用季节时,必须使用SEASON前缀,易与混淆其他静态常量混淆。
- 打印输出的意义不明确:System.out.println(SeasonDemo.Season);输出出的结果是1, 很难猜测1代表春天。

JDK1.5之前,采用类定义的方式实现。方法如下

★通过private将构造器隐藏起来(避免创建对象的随意性,只允许类内创建对象)
★ 把这个类的所有可实例都以public static final 修饰的类变量来保存
★如果有必要,可以提供一些静态方法,允许程序根据特定的参数来获取与之匹配的实例

public class Season
{
    // 把Season类定义成不可变的,将其成员变量也定义成final的
    private final String name;
    private final String desc;
    public static final Season SPRING
        = new Season("春天" , "趁春踏青");
    public static final Season SUMMER
        = new Season("夏天" , "夏日炎炎");
    public static final Season FALL
        = new Season("秋天" , "秋高气爽");
    public static final Season WINTER
        = new Season("冬天" , "围炉赏雪");
    public static Season getSeason(int seasonNum)
    {
    switch(seasonNum)
    {
        case 1 :
            return SPRING;
        case 2 :
            return SUMMER;
        case 3 :
            return FALL;
        case 4 :
            return WINTER;
        default :
            return null;
        }
    }
    // 将构造器定义成private访问权限
    private Season(String name , String desc)
    {
        this.name = name;
        this.desc = desc;
    }
    // 只为name和desc提供getter方法
    public String getName()
    {
        return this.name;
    }
    public String getDesc()
    {
        return this.desc;
    }
}

2、枚举类入门

java5之后增加了关键字enum,它与class、interface的地位相同,用来定义枚举类。
枚举类是一种特殊的类,一样可以有自己的构造器、成员变量、方法,也可以实现一个或多个接口。
枚举类的特点

▲枚举类可以实现一个或者多个接口,使用enum定义的枚举类默认的继承了java.lang.Enum类,而不是默认的继承Object,因此枚举类不能在继承其他父类。其中,java.lang.Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口。
▲使用enum定义的非抽象枚举类不能派生子类。(enum创建的非抽象枚举类,默认采用final修饰,抽象枚举类,系统默认采用abstract修饰)
▲枚举类的构造器只能采用private修饰(默认private)
▲枚举类的实例必须在枚举类的第一行显示列出,否则这个枚举类永远无法产生实例。列出这些是实例时,系统会自动的添加public static final 修饰,无需程序员显式的添加

// SeasonEnum.java
public enum SeasonEnum {
SPRING,SUMMER,FAIL,WINTER;
}
//EnumTest.java
public class EnumTest {
   //判断枚举类型的值
    //形参直接使用枚举类型
    public  void judge(SeasonEnum s){

            switch (s){
             case SPRING: System.out.println("春天到了");break;
             case SUMMER:System.out.println("夏天到了");break;
             case FAIL:    System.out.println("秋天到了");break;
             case WINTER: System.out.println("冬天到了");break;
            }
    }
    public  static void main(String args[]){
        //遍历枚举类,枚举类默认有values()方法
        for (SeasonEnum s:SeasonEnum.values()){
            System.out.println(s);
        }
        //调用judge()函数判断季节
        EnumTest e=new EnumTest();
        e.judge(SeasonEnum.SPRING);
        e.judge(SeasonEnum.SUMMER);
        e.judge(SeasonEnum.FAIL);
        e.judge(SeasonEnum.WINTER);
    }   
}

所有枚举类默认都继承了java.lang.Enum类,所有的枚举类可以直接使用java.lang.Enum类中包含的方法。java.lang.Enum类中提供了如下几个方法
这里写图片描述

3、枚举类的构造器、成员变量、方法

■构造器

public enum Gender {

    //此处的枚举值,通过构造器来创建
    /*
    当为Gender枚举类创建一个Gender(String name)构造器之后,
    应采用下面的方式。在枚举类列举枚举值时,实际上就是调用
    构造器创建枚举类对象,只不过这里无需使用new关键字,也无需
    现式的调用构造器
    等价于
    public static fianl Gender MALE=new Gender("男");
    public static fianl Gender FEMALE=new Gender("女");
     */
    MALE("男"),FEMAL("女");
    //成员变量设计成不可变类型 private final
    private  final String name;
    private Gender(String name){
        this.name=name;
    }
    //不设计set方法。
    public String getName() {
        return this.name;
    }
}

■成员变量

成员变量设计成不可变类型 private final

■方法

不设计set方法。

4、让枚举类实现节口

枚举类也可以实现一个或多个接口。与普通类实现节口一样,枚举类实现一个或者多个接口时,也需要实现该接口所包含的方法。
定义接口

public interface GenderDesc {
   void  info();
}
public enum Gender implements GenderDesc {
    MALE("男"),FEMAL("女") ;
    //重写了interface的方法
        @Override
        public void info() {
            System.out.println("这是一个用于定义性别的枚举类");
        }

    private  final String name;
    private Gender(String name){
        this.name=name;
    }
    public String getName() {
        return this.name;
    }
}

如果由枚举类实现接口里的方法,则每个枚举值在调用该方法时都有相同的行为方式(因为方法体完全一样)。如果需要每个枚举值在调用该方法时,显现出不同的行为方式,则可以让每个枚举值提供不同的实现方式。
如下所示,在上面的基础上,让每个枚举值分别对应不同的info()方法

public enum Gender implements GenderDesc {

/*
花括号部分实际上就是一个匿名内部类,在这种情况下,当创建MALE,FEMAL枚举值时,并不是直接创建Gender枚举类的实例,而是相当于相当于创建Gender的匿名子类的实例

*/
    MALE("男") {
        public void info(){
            System.out.println("这个枚举值代表男");
        }

            },
    FEMAL("女"){
        public void info(){
            System.out.println("这个枚举值代表女");
        }

    }
     ;
    private  final String name;
    private Gender(String name){
        this.name=name;
    }
    public String getName() {
        return this.name;
    }
}

5、包含抽象方法的枚举类

枚举类中有抽象方法时不能使用abstract关键字,因为系统会自动添加abstract关键字

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(5, 4));
        System.out.println(Operation.TIMES.eval(5, 4));
        System.out.println(Operation.DIVIDE.eval(5, 4));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值