如何启用枚举继承

Kir*_*A B 37 java inheritance enums

我正在编写一个库,它具有一组预定义的枚举值.比方说,我的枚举如下所示.

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

    private String httpMethodType;

}
Run Code Online (Sandbox Code Playgroud)

现在,使用此库的客户端可能需要添加更多值.比方说,客户端需要添加CUSTOM_FIRSTCUSTOM_SECOND.这不会覆盖任何现有值,但会使枚举具有5个值.

在此之后,我应该可以使用类似的东西<? extends EnumClass>,有5种不变的可能性.

实现这一目标的最佳方法是什么?

Men*_*ena 46

您不能enum扩展另一个enum,并且不能将值"添加"到现有的enum继承.

但是,enums可以实现interfaces.

我会做的是有原来enum实行标记interface(即没有方法声明),然后客户可以创建自己的enum实现相同interface.

那么你的enum价值观将由他们的共同点引用interface.

为了强化要求,您可以让您的界面声明相关的方法,例如在您的情况下,某些内容public String getHTTPMethodType();.

这将强制实现enums为该方法提供实现.

此设置与适当的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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

产量

first
POST
Run Code Online (Sandbox Code Playgroud)


wer*_*ero 8

枚举不可扩展.简单地解决你的问题

  • 在课堂上转动枚举
  • 为预定义类型创建常量
  • 如果您想要替换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");
    ...
}
Run Code Online (Sandbox Code Playgroud)


小智 6

将 Enum 视为具有自身静态最终实例的最终类。当然你不能扩展 final 类,但是你可以在你的库中使用带有静态 final 实例的非 final 类。您可以在 JDK 中看到此类定义的示例。类 java.util.logging.Level 可以使用包含附加日志级别集的类进行扩展。

如果您接受这种实现方式,您的库代码示例可以是这样的:

public class EnumClass {
    public static final EnumClass FIRST = new EnumClass("first");
    public static final EnumClass SECOND = new EnumClass("second");
    public static final EnumClass THIRD = new EnumClass("third");

    private String httpMethodType;

    protected EnumClass(String name){
        this.httpMethodType = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

客户端应用程序可以通过继承扩展静态成员列表:

public final class ClientEnum extends EnumClass{
    public static final ClientEnum CUSTOM_FIRST = new ClientEnum("custom_first");
    public static final ClientEnum CUSTOM_SECOND = new ClientEnum("custom_second");

    private ClientEnum(String name){
        super(name);    
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为此解决方案与您所要求的很接近,因为所有静态实例都可以从客户端类中看到,并且它们都将满足您的通用通配符。