50 votes

Un enum peut-il avoir des méthodes abstraites ?

Un enum peut-il avoir des méthodes abstraites ? Si oui, quelle en est l'utilité, et donnez un scénario qui illustre cette utilisation.

75voto

smas Points 8299

Oui, mais vous pouvez préférer un enum qui implémente une interface, Regardez ici . Je pense que c'est beaucoup mieux. Ceci est un exemple de méthode abstraite :

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

    public abstract String makeNoise();
}

20voto

Joachim Sauer Points 133411

Oui, vous pouvez définir abstract méthodes dans un enum déclaration si et seulement si toutes les valeurs d'énumération ont des corps de classe personnalisés avec des implémentations de ces méthodes (c'est-à-dire qu'aucune valeur d'énumération concrète ne peut manquer d'implémentation).

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

  public abstract void frobnicate();
}

6voto

sweet suman Points 951

Tout comme la réponse de @lukastymo, il est possible d'implémenter une méthode abstraite dans un enum et il est préférable d'implémenter une interface pour ajouter une méthode dans un enum.

À partir de Java 8, vous pouvez utiliser des lambdas pour implémenter des méthodes dans un enum afin de réduire le code. Ces lambdas peuvent être exécutés en dehors de l'enum en exposant une méthode publique qui exécute le lambda donné.

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

Alors l'enum peut être utilisé comme :

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

Ce n'est pas exactement l'implémentation d'une méthode abstraite à partir de l'enum lui-même ou d'une interface, mais je pense que cette approche d'ajout de méthode en utilisant des lambdas est propre.

5voto

Musa Points 820

Oui, l'enum peut contenir une méthode abstraite - vous pouvez utiliser cette approche si vous avez votre propre implémentation pour les constantes de l'enum. (ou vous pouvez omettre l'utilisation de la méthode abstraite en utilisant une valeur personnalisée pour chaque constante d'énumération. Enum avec valeur personnalisée en Java )

par exemple ( les mises en œuvre de méthodes spécifiques aux constantes )

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

Si cette méthode est commune à toutes les constantes d'enum, envisagez d'utiliser l'interface. (Les enums Java étendent la classe générique java.lang.Enum implicitement, donc vos types d'enum ne peuvent pas étendre une autre classe (parce que Java ne supporte pas l'héritage multiple) mais peuvent implémenter une interface).

interface ColorInterface{
    void inLowerCase();
}

enum Color implements ColorInterface{

    RED, GREEN, ORANGE;

    @Override
    public void inLowerCase(){
        System.out.println(this.toString().toLowerCase());
    }
}

Utilisation :

public class TestEnums{

     public static void main(String []args){
        TrafficSignal signal = TrafficSignal.RED;
        signal.action();

        ColorInterface color = Color.RED;
        color.inLowerCase();
     }
}

Dehors :

STOP
red

Considérez le modèle enum de stratégie si certaines constantes enum, mais pas toutes, partagent des comportements communs. [Effective Java - Joshua Bloch - troisième édition. page 166]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X