浅谈Java枚举类
2018-03-20 21:58
260 查看
什么是枚举类
有时候一个类的对象有且固定的,这样的类就是枚举类。比如说四季,或者是九大行星。这个类突出的特点就是固定。
几个特点
①枚举类默认继承java.lang.Enum类而非Object这个类。
②使用enum修饰,抽象的枚举类会有隐式的abstract修饰,非抽象的枚举类默认使用final修饰所以不能派生子类。(而他的枚举值是他的匿名内部子类)
③构造器默认使用private来修饰。
④枚举值必须在第一行列出分号结尾,当这个枚举值创建实例的时候会使用这些枚举值去实现。默认使用public static final修饰。
创建一个枚举类并且实例化package testEnum;
public enum NameEnum {
HYL,XTJ,LCJ; //他们不是变量,他们是这个类中固定的实例对象的实现类
}
固定的特点
由于枚举类的固定特点,所以导致了枚举类一般不能被外界所修改。一些值直接在构造器中所初始化而不是使用set()方法。代码如下:package newgendertest;
public enum GenderEnum implements GenderDesc{
MALE("男"),FEMALE("女");
private final String name;
private GenderEnum(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}需要注意的是,在枚举类中列出枚举值的时候,实际上是调用构造器创建枚举类对象。无需使用new关键字,也无需显式的调用构造器。在前面的案例中没有使用括号与参数仅仅是因为前面的枚举类包含无参数的构造器。
上面的粗体代码就相当于以下的代码:private static final Gender MILE = new Gender(“男”) ;
private static final Gender FAMILE = new Gender(“女”) ;
实现接口的枚举类
如果由枚举类实现接口中的方法的话,那么其它的枚举值在调用实现方法时就会有相同的行为。如果想让不同的枚举值对象实现不同的行为的话那么就让这些枚举值分别实现不同的功能。代码如下:package newgendertest;
public interface GenderDesc {
void info();
}
事实上粗体部分的代码正是这个枚举类的匿名内部子类的类体。这个东西像是以前学过的匿名内部类。在编译的时候会形成匿名内部子类的的对象,也就是说MILE和FAMILE的本质就是匿名内部子类的对象!有图有真相:
包含抽象方法的枚举类
包含抽象方法的枚举类默认使用abstract修饰,而非final所以它可以派生子类。在枚举类中定义一个抽象方法,枚举值就可以实现这个抽象方法。
有时候一个类的对象有且固定的,这样的类就是枚举类。比如说四季,或者是九大行星。这个类突出的特点就是固定。
几个特点
①枚举类默认继承java.lang.Enum类而非Object这个类。
②使用enum修饰,抽象的枚举类会有隐式的abstract修饰,非抽象的枚举类默认使用final修饰所以不能派生子类。(而他的枚举值是他的匿名内部子类)
③构造器默认使用private来修饰。
④枚举值必须在第一行列出分号结尾,当这个枚举值创建实例的时候会使用这些枚举值去实现。默认使用public static final修饰。
创建一个枚举类并且实例化package testEnum;
public enum NameEnum {
HYL,XTJ,LCJ; //他们不是变量,他们是这个类中固定的实例对象的实现类
}
package testEnum; public class EnumTest { public static void main(String[] args) { for(NameEnum e :NameEnum.values()) { System.out.println(e); } System.out.println(NameEnum.valueOf("HYL")); } }
固定的特点
由于枚举类的固定特点,所以导致了枚举类一般不能被外界所修改。一些值直接在构造器中所初始化而不是使用set()方法。代码如下:package newgendertest;
public enum GenderEnum implements GenderDesc{
MALE("男"),FEMALE("女");
private final String name;
private GenderEnum(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}需要注意的是,在枚举类中列出枚举值的时候,实际上是调用构造器创建枚举类对象。无需使用new关键字,也无需显式的调用构造器。在前面的案例中没有使用括号与参数仅仅是因为前面的枚举类包含无参数的构造器。
上面的粗体代码就相当于以下的代码:private static final Gender MILE = new Gender(“男”) ;
private static final Gender FAMILE = new Gender(“女”) ;
实现接口的枚举类
如果由枚举类实现接口中的方法的话,那么其它的枚举值在调用实现方法时就会有相同的行为。如果想让不同的枚举值对象实现不同的行为的话那么就让这些枚举值分别实现不同的功能。代码如下:package newgendertest;
public interface GenderDesc {
void info();
}
package newgendertest; public enum GenderEnum implements GenderDesc{ MALE("男"){ public void info() { System.out.println("男"); } },FEMALE("女"){ public void info() { System.out.println("女"); } }; private final String name; private GenderEnum(String name) { this.name = name; } public String getName() { return this.name; } }
事实上粗体部分的代码正是这个枚举类的匿名内部子类的类体。这个东西像是以前学过的匿名内部类。在编译的时候会形成匿名内部子类的的对象,也就是说MILE和FAMILE的本质就是匿名内部子类的对象!有图有真相:
包含抽象方法的枚举类
包含抽象方法的枚举类默认使用abstract修饰,而非final所以它可以派生子类。在枚举类中定义一个抽象方法,枚举值就可以实现这个抽象方法。
package abstractenum; public enum AbstractOperationEnum { PLUS { @Override public double eval(double x, double y) { // TODO Auto-generated method stub return 0; } },MINUS { @Override public double eval(double x, double y) { // TODO Auto-generated method stub return 0; } },TIMES { @Override public double eval(double x, double y) { // TODO Auto-generated method stub return 0; } },DIBIDE { @Override public double eval(double x, double y) { // TODO Auto-generated method stub return 0; } }; public abstract double eval(double x,double y); }最后需要说明的是并不是所有的枚举类都使用了final来修饰,非抽象类才用final来修饰所以。所以包含抽象方法的抽象枚举类就可以派生子类。由上面的实验可以得出实现接口的枚举类也能够派生子类。
相关文章推荐
- 【JAVA】浅谈java枚举类
- java程序员从笨鸟到菜鸟之(三十三)异常之浅谈
- 浅谈java中replace()和replaceAll()的区别
- 浅谈JAVA二维数组
- 浅谈Java内存及GC
- 浅谈Java中的hashcode方法
- 浅谈Java的输入输出流
- 【java规范】Java spi机制浅谈
- 浅谈Java中的hashcode方法
- Java设计模式浅谈
- Java spi机制浅谈
- 浅谈java中math类中三种取整函数的区别
- Java枚举类"全方位"
- 浅谈Java中的高精度整数和高精度小数
- 浅谈java中文本框和文本区
- 浅谈java封装思想
- 浅谈Java10 新特性
- 浅谈Java中的hashcode方法
- Java枚举类的基本使用Enum
- Java学习系列(五)Java面向对象之抽象类、接口、内部类、枚举类详解