2016-02-26 66 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