2016-02-26 17 views
16

Piszę bibliotekę, która ma predefiniowany zestaw wartości dla wyliczenia. Powiedzmy, moje wyliczenie wygląda tak, jak poniżej.Jak włączyć dziedziczenie enum

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

    private String httpMethodType; 

} 

Teraz klient, który korzysta z tej biblioteki, może potrzebować dodać kilka dodatkowych wartości. Powiedzmy, że klient musi dodać CUSTOM_FIRST i CUSTOM_SECOND. To nie zastępuje żadnych istniejących wartości, ale powoduje, że wyliczenie ma 5 wartości.

Po tym, powinienem być w stanie użyć czegoś takiego jak <? extends EnumClass>, aby mieć 5 stałych możliwości.

Jakie byłoby najlepsze podejście, aby to osiągnąć?

+1

ten będzie pomocny http://stackoverflow.com/a/478431/3138755 – Rahul

+1

Wyliczenia są dobre, gdy masz pewność co do liczby znanych z możliwych wartości.Jeśli spodziewasz się, że zostanie przedłużony, prawdopodobnie nigdy nie powinieneś używać wyliczeń i przejrzeć temat, dla którego jest przeznaczony twój enum i prawdopodobnie upuść go na korzyść klas implementujących dobrze zaprojektowany interfejs. –

Odpowiedz

20

Nie można uzyskać kolejnego numeru enum i nie można "dodawać" wartości do istniejącego enum poprzez dziedziczenie.

Jednakże, enum s może implementować s może zaimplementować s.

Co chciałbym zrobić, to mieć oryginalny enum wdrożyć znacznik interface (czyli brak oświadczenia metody), wówczas klient może stworzyć swoje własne enum realizacji tego samego interface.

Następnie twoje wartości enum będą określane przez ich wspólny interface.

Aby wzmocnić wymagania, można wyznaczyć interfejsem odpowiednie metody, np. w twoim przypadku coś w linii public String getHTTPMethodType();.

Wymuszenie implementacji enum s w celu zapewnienia implementacji dla tej metody.

To ustawienie w połączeniu z odpowiednią dokumentacją interfejsu API powinno pomóc w dodaniu funkcjonalności w stosunkowo kontrolowany sposób.

Samodzielny przykład (nie myśl leniwe nazwy tutaj)

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

Wyjście

first 
POST 
+0

Podobało mi się to podejście. Jednak jedno zapytanie. Zwykle podczas gdy używamy enum w kodzie, aby użyć go jako wartości domyślnej (stała z podanej listy), używamy czegoś w rodzaju 'LibraryEnum.FIRST'. Jak zasugerowałbyś korzystanie z interfejsu? –

+0

@KiranAB możesz zadeklarować/zaimplementować metodę 'getDefaultValue', zwracając typ' interface'. W ten sposób każde "wyliczenie" będzie musiało zostać zaimplementowane i zwrócić wartość domyślną (lub "null"). – Mena

+0

Jeszcze jedno pytanie. Dodałem metodę, która działa podobnie do valueOf. Teraz w jaki sposób mogę dać mu dostęp statyczny, ponieważ interfejs nie może mieć statycznych metod. A jeśli nie dodaję go do interfejsu, jak wymusić klienta, aby zaimplementować taką metodę. –

3

wyliczenia nie są rozciągliwe. Aby rozwiązać problem, wystarczy

  • włączyć enum w klasie
  • tworzyć stałe dla predefiniowanych typów
  • jeśli chcesz zastąpić Enum.valueOf track wszystkie instancje klasy w mapie statycznej

Na przykład:

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"); 
    ... 
} 
+0

Oto, co miałem na myśli. Jestem całkiem nowy w Javie (zacząłem używać go około 40 dni temu), więc nie mogłem powiedzieć, czy to jest właściwy konstrukt. Po prostu wygląda na niechlujną. Czy radziłbyś posprzątać go trochę? –

+1

co znaleźć niechlujny? – wero