Can an enum have abstract methods?

前端 未结 4 622
伪装坚强ぢ
伪装坚强ぢ 2020-12-05 13:11

Can an enum have abstract methods? If so, what is the use, and give a scenario which will illustrate this usage.

相关标签:
4条回答
  • 2020-12-05 13:27

    Yes, you can define abstract methods in an enum declaration if and only if all enum values have custom class bodies with implementations of those methods (i.e. no concrete enum value may be lacking an implementation).

    public enum Foo {
      BAR {
        public void frobnicate() {
          // do BAR stuff
        }
      },
      BAZ {
        public void frobnicate() {
          // do BAZ stuff
        }
      };
    
      public abstract void frobnicate();
    }
    
    0 讨论(0)
  • 2020-12-05 13:29

    Yes, but you may prefer enum which implements an interface, Look here. I think It looks much better. This is example for abstract method:

    public enum Animal {
        CAT {
            public String makeNoise() { return "MEOW!"; }
        },
        DOG {
            public String makeNoise() { return "WOOF!"; }
        };
    
        public abstract String makeNoise();
    }
    
    0 讨论(0)
  • 2020-12-05 13:32

    Yes enum can contain abstract method - you can use this approach if you have own implementation per enum constants. (or you can omit using abstract method with using customized value per enum constant Enum with customized value in Java)

    for example (constant-specific method implementations)

    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();
    }
    

    If this method is common for all enum constants then consider using interface. (Java enums extend the java.lang.Enum generic class implicitly, so your enum types cannot extend another class(becouse java does not support multiple inheritance) but can implement interface)

    interface ColorInterface{
        void inLowerCase();
    }
    
    enum Color implements ColorInterface{
    
        RED, GREEN, ORANGE;
    
        @Override
        public void inLowerCase(){
            System.out.println(this.toString().toLowerCase());
        }
    }
    

    Usage:

    public class TestEnums{
    
         public static void main(String []args){
            TrafficSignal signal = TrafficSignal.RED;
            signal.action();
    
            ColorInterface color = Color.RED;
            color.inLowerCase();
         }
    }
    

    Out:

    STOP
    red
    

    Consider the strategy enum pattern if some, but not all, enum constants share common behaviors. [Effective Java - Joshua Bloch - third edition. page 166]

    0 讨论(0)
  • 2020-12-05 13:34

    Just like @lukastymo 's answer, it is possible to implement an abstract method in enum and it is preferred to implement an interface when adding a method in an enum.

    From Java 8 and above, you can use lambda to implement methods in an enum for smaller code. These lambda can be executed outside the enum by exposing a public method that runs the given 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);
      }
    }
    

    Then the enum can be used like:

    LocalDate today = LocalDate.of(2019, 9, 18); // 2019 Sep 18
    ScheduleRepeat.DAILY.calculateNextDate(today); // 2019-09-19
    ScheduleRepeat.MONTHLY.calculateNextDate(today); // 2019-10-19
    

    This isn't exactly implementing an abstract method from the enum itself or from an interface, but I think this approach of adding method using lambda looks clean.

    0 讨论(0)
提交回复
热议问题