枚举可以有抽象方法吗?
Posted
技术标签:
【中文标题】枚举可以有抽象方法吗?【英文标题】:Can an enum have abstract methods? 【发布时间】:2011-11-16 20:25:55 【问题描述】:如果有,有什么用,并给出一个场景来说明这种用法。
【问题讨论】:
使用哪种语言?这听起来像是一个家庭作业,如果是这样,请使用家庭作业标签 JAVA。我从未使用带有抽象方法的枚举。我正在尝试了解我可以拥有这样的事情的场景。 不,您正在尝试找出您是否可以拥有这样的东西。编译器会告诉你,我不明白你为什么需要论坛。 【参考方案1】:是的,但您可能更喜欢实现接口Look here 的枚举。我觉得它看起来好多了。这是抽象方法的示例:
public enum Animal
CAT
public String makeNoise() return "MEOW!";
,
DOG
public String makeNoise() return "WOOF!";
;
public abstract String makeNoise();
【讨论】:
在多态的代码示例中总是使用 Animal =)【参考方案2】:是的,您可以在 enum
声明中定义 abstract
方法当且仅当所有枚举值都具有自定义类主体以及这些方法的实现(即可能缺少具体的枚举值一个实现)。
public enum Foo
BAR
public void frobnicate()
// do BAR stuff
,
BAZ
public void frobnicate()
// do BAZ stuff
;
public abstract void frobnicate();
【讨论】:
【参考方案3】:就像@lukastymo 的回答一样,可以在枚举中实现抽象方法,并且在枚举中添加方法时最好实现接口。
从 Java 8 及更高版本开始,您可以使用 lambda 在枚举中实现更小的代码方法。这些 lambda 可以通过公开一个运行给定 lambda 的公共方法在枚举之外执行。
public enum ScheduleRepeat
DAILY(date -> date.plusDays(1)),
WEEKLY(date -> date.plusWeeks(1)),
MONTHLY(date -> date.plusMonths(1)),
QUARTERLY(date -> date.plusMonths(3)),
BIANNUALLY(date -> date.plusMonths(6)),
ANNUALLY(date -> date.plusYears(1)),
;
private final Function<LocalDate, LocalDate> nextDateFunction; // or UnaryOperator<LocalDate>
ScheduleRepeat(Function<LocalDate, LocalDate> nextDateFunction)
this.nextDateFunction = nextDateFunction;
public LocalDate calculateNextDate(LocalDate dateFrom)
return nextDateFunction.apply(dateFrom);
然后枚举可以像这样使用:
LocalDate today = LocalDate.of(2019, 9, 18); // 2019 Sep 18
ScheduleRepeat.DAILY.calculateNextDate(today); // 2019-09-19
ScheduleRepeat.MONTHLY.calculateNextDate(today); // 2019-10-19
这并不完全是从枚举本身或从接口实现抽象方法,但我认为这种使用 lambda 添加方法的方法看起来很干净。
【讨论】:
【参考方案4】:是的,枚举可以包含抽象方法——如果每个枚举常量都有自己的实现,则可以使用这种方法。 (或者您可以省略使用抽象方法,使用每个枚举常量 Enum with customized value in Java 的自定义值)
例如(特定于常量的方法实现)
enum TrafficSignal
RED
@Override
public void action()
System.out.println("STOP");
,
GREEN
@Override
public void action()
System.out.println("GO");
,
ORANGE
@Override
public void action()
System.out.println("SLOW DOWN");
;
public abstract void action();
如果此方法对所有枚举常量都通用,则考虑使用接口。 (Java枚举隐式扩展了java.lang.Enum泛型类,所以你的枚举类型不能扩展另一个类(因为java不支持多重继承)但可以实现接口)
interface ColorInterface
void inLowerCase();
enum Color implements ColorInterface
RED, GREEN, ORANGE;
@Override
public void inLowerCase()
System.out.println(this.toString().toLowerCase());
用法:
public class TestEnums
public static void main(String []args)
TrafficSignal signal = TrafficSignal.RED;
signal.action();
ColorInterface color = Color.RED;
color.inLowerCase();
输出:
STOP
red
如果一些(但不是全部)枚举常量具有共同的行为,请考虑策略枚举模式。 [Effective Java - Joshua Bloch - 第三版。第 166 页]
【讨论】:
以上是关于枚举可以有抽象方法吗?的主要内容,如果未能解决你的问题,请参考以下文章