Comment activer l'héritage enum

j'écris une bibliothèque, qui a un ensemble prédéfini de valeurs pour un enum. Disons que mon enum est comme ci-dessous.

public enum EnumClass {
    FIRST("first"),
    SECOND("second"),
    THIRD("third");

    private String httpMethodType;

}

maintenant le client, qui utilise cette bibliothèque peut avoir besoin d'ajouter quelques valeurs supplémentaires. Disons, le client doit ajouter CUSTOM_FIRST et CUSTOM_SECOND. Cela ne remplace aucune valeur existante, mais rend l'enum avoir 5 valeurs.

après cela, je devrais pouvoir utiliser quelque chose comme <? extends EnumClass> avoir 5 possibilités constantes.

Ce qui serait la meilleure approche pour y parvenir?

24
demandé sur Kiran A B 2016-02-26 14:02:49

3 réponses

Vous ne pouvez pas avoir un enum étendre un autre enum, et vous ne pouvez pas "ajouter" des valeurs à un enum par le biais de l'héritage.

Cependant, enum S peut implémenter interfaces.

Ce que je voudrais faire est d'avoir l'original enum implémenter un marqueur interface (C.-à-d. Aucune déclaration de méthode), alors votre client pourrait créer son propre enum implémenter le même interface.

Puis enum les valeurs seraient référencées par leur interface.

afin de renforcer les exigences, vous pouvez demander à votre interface de déclarer des méthodes pertinentes, par exemple dans votre cas, quelque chose dans les lignes de public String getHTTPMethodType();.

ce serait forcer la mise en œuvre de enums pour fournir une implémentation de cette méthode.

ce paramètre combiné à une documentation API adéquate devrait aider à ajouter des fonctionnalités d'une manière relativement contrôlée.

Autonome (ne vous occupez pas des paresseux les noms ici)

package test;

import java.util.ArrayList;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        List<HTTPMethodConvertible> blah = new ArrayList<>();
        blah.add(LibraryEnum.FIRST);
        blah.add(ClientEnum.BLABLABLA);
        for (HTTPMethodConvertible element: blah) {
            System.out.println(element.getHTTPMethodType());
        }
    }

    static interface HTTPMethodConvertible {
        public String getHTTPMethodType();
    }
    static enum LibraryEnum implements HTTPMethodConvertible {
        FIRST("first"),
        SECOND("second"),
        THIRD("third");
        String httpMethodType;
        LibraryEnum(String s) {
            httpMethodType = s;
        }
        public String getHTTPMethodType() {
            return httpMethodType;
        }
    }
    static enum ClientEnum implements HTTPMethodConvertible {
        FOO("GET"),BAR("PUT"),BLAH("OPTIONS"),MEH("DELETE"),BLABLABLA("POST");
        String httpMethodType;
        ClientEnum(String s){
            httpMethodType = s;
        }
        public String getHTTPMethodType() {
            return httpMethodType;
        }
    }
}

Sortie

first
POST
33
répondu Mena 2016-02-26 11:14:45
  • activer l'enum dans une classe
  • créer des constantes pour les types prédéfinis
  • si vous voulez un remplacement de Enum.valueOf: suivi de toutes les instances de la classe dans une carte statique

Par exemple:

public class MyType {
    private static final HashMap<String,MyType> map = new HashMap<>();
    private String name;
    private String httpMethodType;

    // replacement for Enum.valueOf
    public static MyType valueOf(String name) {
         return map.get(name);
    }

    public MyType(String  name, String httpMethodType) {
         this.name = name;
         this.httpMethodType = httpMethodType;
         map.put(name, this);
    }

    // accessors
    public String name() { return name; }
    public String httpMethodType() { return httpMethodType; }

    // predefined constants
    public static final MyType FIRST = new MyType("FIRST", "first");
    public static final MyType SECOND = new MyType("SECOND", "second");
    ...
}
6
répondu wero 2016-02-26 11:18:32

nous avons réglé la question de l'héritage d'enum de cette façon, espérons que cela aide

notre application a peu de classes et chacune a peu de vues d'enfant(vues emboîtées), afin d'être en mesure de naviguer entre les vues d'enfant et de sauver la vue actuelle de enfant, nous les avons sauvés en tant qu'enum à l'intérieur de chaque classe. mais nous avons dû copier coller, certaines fonctionnalités comme le suivant, précédent et etc à l'intérieur de chaque enum. Pour éviter que nous ayons besoin D'un BaseEnum, nous avons utilisé l'interface comme notre enum de base:

public interface IBaseEnum {
    IBaseEnum[] getList();
    int getIndex();

    class Utils{
        public IBaseEnum next(IBaseEnum enumItem, boolean isCycling){
            int index = enumItem.getIndex();
            IBaseEnum[] list = enumItem.getList();
            if (index + 1 < list.length) {
                return list[index + 1];
            } else if(isCycling)
                return list[0];
            else
                return null;
        }

        public IBaseEnum previous(IBaseEnum enumItem, boolean isCycling) {
            int index = enumItem.getIndex();
            IBaseEnum[] list = enumItem.getList();

            IBaseEnum previous;
            if (index - 1 >= 0) {
                previous = list[index - 1];
            }
            else {
                if (isCycling)
                    previous = list[list.length - 1];
                else
                    previous = null;
            }
            return previous;
        }
    }
}

et c'est ainsi que nous avons utilisé

enum ColorEnum implements IBaseEnum {
    RED,
    YELLOW,
    BLUE;
    @Override
    public IBaseEnum[] getList() {
        return values();
    }

    @Override
    public int getIndex() {
        return ordinal();
    }

    public ColorEnum getNext(){
    return (ColorEnum) new Utils().next(this,false);
    }

    public ColorEnum getPrevious(){
        return (ColorEnum) new Utils().previous(this,false);
    }
}

vous pouvez ajouter getNext /getPrevious à l'interface aussi

0
répondu Annie 2018-05-25 20:14:24