Comment fonctionnalités Hériter pour réduire la répétition des codes dans les énumérations?

Carven:

Dans une application Java , je travaille, j'ai un certain nombre d'énumérations qui a fini par avoir une statique fromStringméthode pour les convertir une chaîne à sa valeur réelle ENUM.

Donc, je pensais que je pourrais avoir une classe « de base » à partir de laquelle tous mes énumérations peuvent prolonger sans avoir à répéter ce code tout le temps. Étant donné que les énumérations ne peuvent pas étendre les classes, je l'ai prévu de faire est que je pourrais être en mesure de le faire à travers une interface à la place.

Ce que j'ai est le suivant:

public interface IBaseEnum {

    String enumVal = null;

    public static <T extends Enum<T> & IBaseEnum> Enum<T> fromString(String strVal) {
        if (strVal == null) return null;
        // T.values() has error because T is not recognised to have the method values()
        for (T myEnum : T.values()) {
            if (myEnum.enumVal.equals(strVal.toUpperCase())) {
                return myEnum;
            }
        }
        return null;
    }
}

Et puis, pour hériter de cette méthode statique, je vais mettre en œuvre IBaseEnumdans mon Enum réelle:

public enum Colour implements IBaseEnum {
   Red("red");
   //...
}

Cependant, je vais avoir des problèmes avec les types en IBaseEnum. La ligne T.values()est d' avoir une erreur parce que le type générique Tne peut pas être référencé retour à l'ENUM lui - même et il se plaint que la méthode values()ne se trouve pas.

Est-ce la bonne façon de fonctionnalités Hériter ENUM? Sinon, comment puis-je hériter des méthodes dans les énumérations pour que je n'ai pas à copier / coller et répéter un même ensemble de méthodes dans tous les énumérations simples?

ernest_k:

Il y a quelques raisons pour lesquelles votre code ne marcherait pas, dont je dois mentionner:

  • String enumVal = null;: IBaseEnumÊtre une interface, numValobtient les implicites public, staticet finalmodificateurs. Cependant, vous avez l' intention enumVald'être une propriété d'instance.
  • T.values(): Bien sûr, cela ne compile pas. Mais même si elle pouvait (ou vous avez eu l'instance de classe), vous ne toujours pas être en mesure de faire cette dynamique. Les méthodes statiques sont cueillies au moment de la compilation. La seule façon (que je sache) pour le faire fonctionner serait dynamiquement être à la réflexion de l'utilisation, de passer bien sûr dans l'objet de classe de l'ENUM.

Parce que vous voulez être en mesure d'appeler Color.fromString(...), vous avez pas d'autre choix que de déclarer cela comme une méthode statique dans chaque classe ENUM. Cela dit, je pense que le plus vous pouvez réutiliser à partir de votre logique est le code de recherche (encore une fois, c'est à moins que vous utilisez la réflexion).

Pour réutiliser la logique de recherche, vous pouvez modifier le contrat de IBaseEnumle faire déclarer une méthode qui retourne la enumValvaleur. A côté de cela, la values()méthode peut être invoquée par les classes elles - mêmes ENUM. Voici ce qu'il peut ressembler à :

interface IBaseEnum {

    String enumVal();

    public static <T extends Enum<T> & IBaseEnum> T 
                 fromString(String strVal, T[] values) {

        if (strVal == null)
            return null;

        for (T myEnum : values) {
            if (myEnum.enumVal().equalsIgnoreCase(strVal)) {
                return myEnum;
            }
        }

        return null;
    }
}

Et cela conduira à une classe enum comme suit:

enum Colour implements IBaseEnum {
    VAL1("string")
    ;

    private final String val;

    Colour(String v) {
        this.val = v;
    }

    @Override
    public String enumVal() {
        return this.val;
    }

    public static Colour fromString(String s) {
        return IBaseEnum.fromString(s, values());
    }
}

Rappelez - vous: si enumVal()est destiné à revenir juste le ENUM littéral, alors vous pouvez vous débarrasser de toute cette complexité en utilisant simplement la valueOfméthode disponible dans toutes les énumérations. Seulement faire si la comparaison de vos valeurs a besoin une logique personnalisée.

Je suppose que tu aimes

Origine http://10.200.1.11:23101/article/api/json?id=427288&siteId=1
conseillé
Classement