枚举enum实现抽象方法
2019-07-06 本文已影响0人
哈密朵
这是一个常见的枚举类,枚举由成员属性和成员方法组成,偶尔有静态方法,静态方法用来遍历所有实例,判断实例的成员属性值等。枚举第一排就是各个单例实例,配合private构造函数把入参值构造给成员属性上。
字节码层面,这个普通的枚举是final class:
public final class com.xxx.AreaType extends java.lang.Enum<com.xxx.AreaType>
public enum AreaType {
OUTER("0", "内"), INNER("1", "外");
private String type;
private String name;
AreaType(String type, String name) {
this.type = type;
this.name = name;
}
public String getType() {return type;}
public String getName() {return name;}
public static AreaType typeOf(String type) {
for (AreaType areaType: AreaType.values()) {
if (areaType.type.equals(type)) {
return areaType;
}
}
return null;
}
}
成员方法是直接使用成员属性比如type和name计算得到返回结果,静态方法是遍历各个实例使用其成员属性计算得到返回结果,方法过程都是根据成员属性进行计算。
如果我们想让各个实例拥有完全不一样的方法实现,不依赖于成员属性,有三种方式:
1)定义抽象方法,实例使用{...}匿名块,在匿名块中实现抽象。
OUTER("0", "区域内") {
@Override
public Date elapseDate(Date date, int quantity) {
return DateUtils.addDays(date, quantity);
}
}
public String getType() {return type;}
public String getName() {return name;}
public abstract Date elapseDate(Date date, int quantity);
字节码层面,定义了抽象方法后,则枚举类在字节码层面是abstract class,各个单例实例加上了匿名实现块{...} 之后变成了final 子class。
public abstract class com.xxx.AreaType extends java.lang.Enum<com.xxx.AreaType>
第一个实例OUTER:
final class com.xxx.AreaType$1 extends com.xxx.AreaType
2)定义额外的接口,枚举实现接口,各个实例使用{...}匿名块,在匿名块中实现接口。
public enum AreaType implements IDateHandler {
OUTER("0", "区域内") {
@Override
public Date elapseDate(Date date, int quantity) {
return DateUtils.addDays(date, quantity);
}
}
public String getType() {return type;}
public String getName() {return name;}
}
字节码层面跟抽象方法类似,多了一个接口定义
public abstract class com.xxx.AreaType extends java.lang.Enum<com.xxx.AreaType> implements com.xxx.IDateHandler
第一个实例OUTER:
final class com.xxx.AreaType$1 extends com.xxx.AreaType
3)成员属性增加一个接口引用,在调用构造函数时,填入一个匿名接口实现或一个表达式,新建成员方法,内部使用接口成员属性去执行一系列处理。
OUTER("0", "区域内", (date, quantity) -> DateUtils.addDays(date, quantity));
private String type;
private String name;
private IDateHandler handler;
AreaType(String type, String name, IDateHandler handler) {
this.type = type;
this.name = name;
this.handler = handler;
}
public String getType() {return type;}
public String getName() {return name;}
public Date handleDate(Date date, int quantity) {
return handler.elapseDate(date, quantity);
}