【问题标题】:Can an enum have abstract methods?枚举可以有抽象方法吗?
【发布时间】:2011-11-16 20:25:55
【问题描述】:

枚举可以有抽象方法吗?如果有,有什么用,并给出一个场景来说明这种用法。

【问题讨论】:

  • 使用哪种语言?这听起来像是一个家庭作业,如果是这样,请使用家庭作业标签
  • JAVA。我从未使用带有抽象方法的枚举。我正在尝试了解我可以拥有这样的事情的场景。
  • 不,您正在尝试找出您是否可以拥有这样的东西。编译器会告诉你,我不明白你为什么需要论坛。

标签: java enums abstract


【解决方案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 页]

      【讨论】:

        猜你喜欢
        • 2014-02-13
        • 1970-01-01
        • 2011-08-31
        • 1970-01-01
        • 2022-06-25
        • 1970-01-01
        • 2016-02-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多