2016-02-26 93 views
16

我在寫一個庫,它有一組枚舉的預定義值。讓我說,我的枚舉看起來如下。如何啓用枚舉繼承

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

    private String httpMethodType; 

} 

現在,使用此庫的客戶端可能需要添加更多的值。假設客戶需要添加CUSTOM_FIRSTCUSTOM_SECOND。這不會覆蓋任何現有的值,但會使枚舉具有5個值。

在此之後,我應該能夠使用像<? extends EnumClass>這樣的東西有5個不變的可能性。

什麼是最好的方法來實現這一目標?

+1

這將有利於http://stackoverflow.com/a/478431/3138755 – Rahul

+1

當你明確知道可能的已知值的數量時,枚舉是很好的。如果你期望它被擴展,你可能永遠都不應該使用枚舉,並且檢查你當前枚舉的設計目標,並且可能會放棄實現精心設計的界面的類。 –

回答

20

您不能讓enum擴展另一個enum,並且您不能通過繼承將值「添加」到現有的enum

但是,enum s可以實施interface s。

我會做的是有原來的enum實現一個標記interface(即沒有方法聲明),然後客戶可以創建自己的enum實現相同interface

然後你的enum值將被它們共同的interface引用。

爲了加強要求,你可以讓你的接口聲明相關的方法,例如在你的情況,在public String getHTTPMethodType();行的東西。

這將強制執行enum s爲該方法提供實現。

此設置加上適當的API文檔應該有助於以相對受控的方式添加功能。

自足例如(不介意這裏的慵懶名)

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

輸出

first 
POST 
+0

我喜歡這種方法。但是,一個查詢。 通常,雖然我們在代碼中使用enum將其用作默認值(來自給定列表的常量),但我們使用類似於「LibraryEnum.FIRST」的東西。 當你通過界面時你會如何使用? –

+0

@KiranAB你可以聲明/實現一些'getDefaultValue'方法,返回''interface''的類型。這樣每個'enum'都必須實現它,並返回一個默認值(或'null')。 – Mena

+0

還有一個問題。我添加了一個類似於valueOf的方法。現在我怎麼給它靜態訪問,因爲接口不能有靜態方法。如果我不在接口中添加它,我如何強制客戶端實現這種方法.. –

3

枚舉是不可擴展的。爲了解決你的問題簡單地

  • 打開枚舉類中的
  • 創建預定義類型的常量
  • ,如果你想爲 Enum.valueOf更換
  • :跟蹤類的所有實例的靜態地圖

例如:

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

這就是我想到的。我對java很陌生(在40天前開始使用它),所以不能說這是否是正確的構造。只是它看起來有些雜亂。你會建議把它清理一下嗎? –

+1

發現什麼雜亂? – wero