enum枚举类

枚举类

Tags: enum


枚举类入门

枚举类是一个特殊的类, 它一样可以有自己的属性和方法, 可以实现一个或者多个接口, 也可以定义自己的构造器。

枚举类与普通类有以下区别:

  1. 使用enum定义的枚举类默认继承java.lang.Enum这个类, 而不像普通类一样默认继承java.lang.Object类。 其中java.lang.Enum这个类实现了java.lang.Serializablejava.lang.Comparable两个接口。

  2. 枚举类的构造方法只能用private修饰, 如果没有modifier, 则默认为private

  3. 枚举类的所有势力都必须在枚举类中显式列出, 否则这个枚举类都将永远不能产生实例。列出实例时, 系统自动添加public static final修饰,无需显式添加。

  4. 所有枚举类都提供给了一个values()方法, 返回该枚举类的所有实例

例:

“`
public enum Season {

SPRING, SUMMER, AUTUMN, WINTER;

}
“`

以上代码等同于:

“`
public enum Season {

   public static final SPRING;
   public static final SUMMER;
   public static final AUTUMN;
   public static final WINTER;

   private Season() {
   }

}
“`

测试:

“`
public class TestSeason {

   public static void main(String[] args) {

       for (Season s : Season.values()) {
           System.out.println(s);
       }
   }

}
“`

输出:


SPRING
SUMMER
AUTUMN
WINTER

枚举类的属性、方法、构造方法

枚举类也是一种类, 不过是一种比较挺特殊的类,但是一样可以有属性和方法。

先看一个简单的例子:

   public enum Gender {

       MALE, FEMALE;

       private String name;

       public void setName(String name) {
           switch (this) {
           case MALE :
               if (name.equals("man")) {
                   this.name = name;
               } else {
                   System.out.println(name +  " is not correct.")
                   return;
               }
               break;
           case FEMALE :
               if (name.equals("woman")) {
                   this.name = name;
               } else {
                   System.out.println(name +  " is not correct.")
                   return;
               }
               break;    
           }
       }
   } 

上面的代码可以是可以, 但是不是最优,首先它略显啰嗦累赘。其次,枚举类通常应该设计成不可变类, 也就是说它的属性不应该允许改变, 这样会更加安全而且更加简洁。 因此, 应该将枚举类的属性都使用private final修饰。

因为我们将所有属性都用了final来修饰, 所以必须在构造器里为这些属性制定初始值,也就是说为枚举类显式的定义带参数的构造方法。一旦为枚举类显式定义了带参数的构造方法, 则列出枚举值时也必须对应的传入参数(可以把枚举类里列出枚举值的过程看成创建一个该枚举类对象的过程,但无需使用new这个关键字, 也无需显式的调用构造器。创建对象调用该枚举类带参数的构造方法,所以在列出枚举值时也要相应的传入参数 )

所以把上面的代码改成:

   public enum Gender {

       MALE("man"),
       FEMALE("woman");

       private final String name;

       private Gender(String name) {
           this.name = name;
       }
   }

实现接口的枚举类

枚举类也可以实现一个或者多个接口, 与普通类一样, 枚举类实现接口时, 也必须实现接口所包含的所有方法。

如果由枚举类来实现接口里的方法, 那么每个枚举值在调用该方法的时候, 都会有相同的行为方式(因为方法体完全一样)。如果需要每个枚举值在调用该方法时呈现出不同的行为方式, 可以让每个枚举值分别来实现该方法, 每个枚举值提供不同的行为方式(每个枚举值对接口里的方法有不同的重写)。

例:让上面的Gender类实现IGender接口, 并且让MALEFEMALE对接口里的方法进行不同的重写

   interface IGender {
       public void info();
   }

   public enum Gender implements IGender {

       MALE("man") {
           public void info() {
               System.out.println("This is a man");
           }
       },
       FEMALE("woman") {
           public void info() {
               System.out.println("This is a woman");
           }
       };

       private Gender(String name) {
           this.name = name;
       }
   }

测试:

“`
public class TestGender {

   public static void main(String[] args) {

       Gender.MALE.info();
       Gender.FEMALE.info();
   }

}
“`
结果:

   This is a man
   This is a woman

上面的代码乍看有点奇怪, 但是仔细看看, 发现它好像匿名内部类的写法。在这种情况下, 当创建MALE、FEMALE枚举值时, 并不是直接创建Gender枚举类的实例,而是相当于创建Gender的匿名子类的实例。编译上面的程序, 可以看到生成了Gender.class、Gender 1.classGender 2.class三个文件,证明了上面的结论。

包含抽象方法的枚举类

假设有一个Calculator枚举类,它的四个枚举值PLUS,MINUS,TIMES,DIVIDE分别代表加减乘除。

   public enum Operator {

       `PLUS`,`MINUS`,`TIMES`,`DIVIDE`double calculate(double x, double y) {
            double calculate(double x, double y) {
                switch (this) {
                    case PLUS:
                        return x + y;
                    case MINUS:
                        return x - y;
                    case TIMES:
                        return x * y;
                    case DIVIDE:
                        return x / y;
                    default:
                        return 0;
               }
            }
       }
   }

上面代码中default这段代码完全没有必要写。四个枚举值对calculate(double x, double y)这个方法都有不同的实现, 可以考虑写成这个枚举类实现某个接口, 接口里的方法是calculate(double x, double y)

   interface IOperator {
       public double calculate(double x, double y);
   }

   public enum Operator implements IOperator {
        PLUS {
            public double calculate(double x, double y) {
            return x + y;
            }
        }, 
        MINUS {
            public double calculate(double x, double y) {
            return x - y;
            }
        }, 
        TIMES {
            public double calculate(double x, double y) {
            return x * y;
            }
        }, 
        DIVIDE{
            public double calculate(double x, double y) {
            return x / y;
            }
        };
   }

也可以直接在Operator里直接定义一个calculate的抽象方法 :

   public enum Operator implements IOperator {
        PLUS {
            public double calculate(double x, double y) {
            return x + y;
            }
        }, 
        MINUS {
            public double calculate(double x, double y) {
            return x - y;
            }
        }, 
        TIMES {
            public double calculate(double x, double y) {
            return x * y;
            }
        }, 
        DIVIDE{
            public double calculate(double x, double y) {
            return x / y;
            }
        };

        public abstract double calculate(double x, double y);
   }

学习抽象类的时候,如果方法被生命为abstract, 那么类必须也要声明为abstract,但是在枚举类里定义抽象方法时无需显式的使用abstract关键字将枚举类定义为抽象类这是因为:枚举类需要显式的创建枚举值, 而不是作为父类, 所以定义每个枚举值时必须为抽象方法提供实现, 否则编译出错

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值