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?
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 interface
s.
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 enum
s 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
- 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");
...
}
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