Подтвердить что ты не робот

Может ли перечисление иметь абстрактные методы?

Может ли перечисление иметь абстрактные методы? Если да, то какое использование и дать сценарий, который иллюстрирует это использование.

4b9b3361

Ответ 1

Да, но вы можете предпочесть enum, который реализует интерфейс, Посмотрите здесь. Я думаю, это выглядит намного лучше. Это пример абстрактного метода:

public enum Animal {
    CAT {
        public String makeNoise() { return "MEOW!"; }
    },
    DOG {
        public String makeNoise() { return "WOOF!"; }
    };

    public abstract String makeNoise();
}

Ответ 2

Да, вы можете определить методы abstract в объявлении enum , если и только если все значения перечисления имеют собственные тела классов с реализациями этих методов (то есть, нет конкретного значения перечисления может отсутствовать реализация).

public enum Foo {
  BAR {
    public void frobnicate() {
      // do BAR stuff
    }
  },
  BAZ {
    public void frobnicate() {
      // do BAZ stuff
    }
  };

  public abstract void frobnicate();
}

Ответ 3

Да, enum может содержать абстрактный метод - вы можете использовать этот подход, если у вас есть собственная реализация для каждого константы enum. (или вы можете опустить использование абстрактного метода с использованием настраиваемого значения на константу перечисления Enum с настраиваемым значением в 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();
     }
}

Out:

STOP
red

Рассмотрите шаблон перечисления стратегии, если некоторые, но не все константы перечисления имеют общее поведение. [Эффективная Ява - Джошуа Блох - третье издание. страница 166]

Ответ 4

Как и в случае ответа @lukastymo, в enum можно реализовать абстрактный метод, и предпочтительнее реализовать интерфейс при добавлении метода в enum.

Начиная с Java 8 и выше, вы можете использовать лямбду для реализации методов в перечислении для меньшего кода. Эти лямбда-выражения можно выполнять вне перечисления, предоставляя открытый метод, который запускает заданную лямбда-выражение.

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

Это не совсем реализация абстрактного метода из самого перечисления или из интерфейса, но я думаю, что этот подход добавления метода с использованием лямбды выглядит чистым.