当前位置: 首页 > 面试题库 >

如何为一些Java枚举添加通用方法?(抽象类祖先?)

叶元凯
2023-03-14
问题内容

我有几个这样的Java枚举

public enum Aggregation
{
    MORTGAGE( "Mortgage" ),
    POOLS( "Pools" ),
    PORTFOLIO( "Portfolio" );

    private Aggregation( final String name )
    {
        m_Name = name;
    }
    private String m_Name;
    static Map< String, Aggregation > c_LOOKUP =
        new HashMap< String, Aggregation >();
    static {
        for (Aggregation agg:values()){
            c_LOOKUP.put(agg.m_Name,agg);
        }
    }

    public Aggregation lookup(String name){
        return c_LOOKUP.get( name );
    }

    @Override
    public String toString()
    {
        return m_Name;
    }
}

public enum Interval
{
    MONTHLY( "Monthly" ),
    QUARTLY( "Quartly" ),
    SEMIANNUALLY( "SemiAnnually" ),
    ANNUALLY("Annually");

    private Interval( final String name )
    {
        m_Name = name;
    }
    private String m_Name;
    static Map< String, Interval > c_LOOKUP =
        new HashMap< String, Interval >();
    static {
        for (Interval agg:values()){
            c_LOOKUP.put(agg.m_Name,agg);
        }
    }

    public Interval lookup(String name){
        return c_LOOKUP.get( name );
    }

    @Override
    public String toString()
    {
        return m_Name;
    }
}

如您所见,这里有很多代码重复。如果有一种方法可以引入诸如抽象的共同祖先类之类的东西,那就太好了。但是java枚举不能固有。最好的方法是什么?谢谢。

编辑:我已经制定出一个类似于ŁukaszBachman和missingfacktor的版本

static public enum Aggregation
{
    MORTGAGE( "Mortgage" ),
    POOLS( "Pools" ),
    PORTFOLIO( "Portfolio" );

    private final String m_Name;

    final static private ReverseDictionary< Aggregation > c_DICTIONARY =
        new  ReverseDictionary< Aggregation >( Aggregation.class );

    static public Aggregation lookup( final String name )
    {
        return c_DICTIONARY.lookup( name );
    }

    private Aggregation( final String name )
    {
        m_Name = name;
    }

    @Override
    public String toString()
    {
        return m_Name;
    }
}

static public enum Interval
{
    MONTHLY( "Monthly" ),
    QUARTLY( "Quartly" ),
    SEMIANNUALLY( "SemiAnnually" ),
    ANNUALLY( "Annually" );

    private final String m_Name;
    final static private ReverseDictionary< Interval > c_DICTIONARY =
        new ReverseDictionary< Interval >( Interval.class );

    static public Interval lookup( final String name )
    {
        return c_DICTIONARY.lookup( name );
    }

    private Interval( final String name )
    {
        m_Name = name;
    }

    @Override
    public String toString()
    {
        return m_Name;
    }
}


static public class ReverseDictionary< E extends Enum< E >>
{
    Map< String, E > c_LOOKUP = new HashMap< String, E >();

    public ReverseDictionary( final Class< E > enumClass )
    {
        for( final E agg : EnumSet.allOf( enumClass ) )
        {
            c_LOOKUP.put( agg.toString(), agg );
        }
    }

    public E lookup( final String name )
    {
        return c_LOOKUP.get( name );
    }

}

我看到了一些推理。但是,它仍然不是很令人满意。

  1. lookup(String)由于返回类型不同,因此很难为其定义接口
  2. 我可以理解,lookup(String)不是真正的重复,而是一个规范,但是我仍然感到m_Name字段和toString()逻辑有点多余。我们实际上是在指定一种枚举类型,在我看来,这似乎是 “是” 关系。

问题答案:

为了接口而 偏爱 继承编程上的 组合
。由于枚举是类(不是常规的,但仍然是类),因此您可以创建一些包含共享逻辑的字段,让枚举实现您的接口并将实现委派给该字段。

相关代码段:

共享界面

public interface MyInterface {

    void someMethod();

}

逻辑实现

public class MyInterfaceImpl implements MyInterface {

    public void someMethod() {
        System.out.println("Do smth...");
    }

}

第一个枚举

public enum EnumA implements MyInterface {
    ;

    private MyInterface impl = new MyInterfaceImpl();

    public void someMethod() {
        impl.someMethod();
    }

}

第二枚举

public enum EnumB implements MyInterface {
    ;

    private MyInterface impl = new MyInterfaceImpl();

    public void someMethod() {
        impl.someMethod();
    }

}

请大家注意,EnumAEnumB不是真正的重复代码,因为这是普通的委托(有效的,在我看来)。还请注意,使用接口可以将所有内容很好地粘合在一起。



 类似资料:
  • 问题内容: 在Java中,您可以: 您如何在Scala中做到这一点? 编辑/有用的链接: https://github.com/rbricks/itemized http://pedrorijo.com/blog/scala-enums/ 问题答案:

  • 问题内容: 有这样的事情: 抽象类: 和扩展器: 我想要的是扩展,因为如果不处理它,然后尝试在中处理它。例如add- 但同时让类处理默认值,例如。 这是完全错误的方法吗? 到目前为止,我所做的就是添加一个接口。通常: 在课堂上: 在课堂上: 这看起来像是可用的设计吗? 并且,主要问题: 有没有什么好办法扩展该类,以便可以使用与in 中相同的切换方法?我想知道的是,有没有一个更好的设计,第二个是是否

  • 本文向大家介绍Java枚举抽象方法实例解析,包括了Java枚举抽象方法实例解析的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了Java枚举抽象方法实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 需求背景 需求已经确定了几个固定的常量值,并且每个常量值都有相同的行为,但是具体实现细节不同。建议使用枚举抽象方法,优点:结构清晰,便

  • 问题内容: 考虑以下(简化的)枚举: 可以在以下函数中使用它: 我现在想为此编写一个单元测试,以模拟每个枚举实例中对myMethod()的调用。我尝试了以下方法: 但是,真正的实现和正在调用。 我做错了什么? 问题答案: 枚举中的每个常量都是一个静态的最终嵌套类。因此,要模拟它,您必须在PrepareForTest中指向嵌套类。 返回预初始化的数组,因此在您的情况下也应进行模拟。 每个枚举常量都只

  • 问题内容: 帮我了解泛型。说我有两个枚举作为内部类,如下所示: 我不想让两个枚举都实现一个接口,而不得不两次实现相同的方法,而是希望在外部类中有一个方法可以执行以下操作: 但是,此方法无法编译。我要尝试做的是找出字符串值是否为枚举值的名称(在任何枚举中),无论是蔬菜,水果,还是其他。不管这实际上是否是冗余方法,我尝试(重新)编写的方法有什么问题? 基本上我想这样做: 问题答案: 原来有几个问题:

  • 问题内容: 枚举可以有抽象方法吗?如果是这样,有什么用,并给出一个场景来说明这种用法。 问题答案: 是的,但是您可能更喜欢实现接口的枚举,请看这里。我认为它看起来好多了。这是抽象方法的示例: