【问题标题】:Java enum extends workaroundJava 枚举扩展了解决方法
【发布时间】:2013-10-03 09:21:19
【问题描述】:

还有比这更好的“解决方法”吗?在访问 TableMap 上的方法时,我想避免使用 PREFIX(本地变量)。

public class TableMap extends TreeMap<String, String> {
    public String field1, field2, field3;
    public TableMap(Tables table){}
    public void method(){}
    public void method2(){}
    public void method3(){}
    ...
}

解决方法!

public enum Tables {
    table1, table2, table3;
    public final TableMap MAP=new TableMap(this);
    private Tables(){}
}

需要!

public enum Tables extends TableMap {
    table1, table2, table3;
    public Tables(){
        super(table);
    }
}

整个代码中的示例:

    // workaround!
    Tables.table1.MAP.method();
    Tables.table2.MAP.method();
    Tables.table3.MAP.method();
    ...

    // needed!
    Tables.table1.method();
    Tables.table2.method();
    Tables.table3.method();
    ...

【问题讨论】:

  • 这个问题(虽然看起来很有价值,很好)有点不清楚,请添加更多上下文。

标签: java inheritance enums


【解决方案1】:

在 Java 中,enum 类型必须扩展 java.lang.Enum。由于 Java 类型只能扩展一个类型,您可能认为 public class TableMap extends Enum 可能有效,但不,编译器不允许这样做。

在我自己的代码中,我经常将enums 仅用作键,因为它们非常具有敌意。我让他们实现一个通用接口,然后使用工厂查找我可以使用的“worker”实例的特定实现。

一种更接近您想要的语法的方法是使用委托模式:

public enum Tables {
    ...
    public void method() {
        MAP.method();
    }
}

【讨论】:

  • 我明白了,但不是最好的方法,方法太多了!
  • 使用您的 IDE 生成方法。
  • 除此之外Map 接口还有一个values() 方法,它的签名不同于Enums,所以你不能有一个枚举实现Map
  • @BlankChisui:不错的收获。我的方法允许重命名该方法,以便您可以访问它。但它排除了这种情况下的继承,即使我们可以通过某种方式实现它。
【解决方案2】:

我认为您可能试图在enum 中投入过多的情报。

我发现这种方法非常有用。它避免了许多由于您无法扩展enums 而引起的问题(实际上您可以但不是以非常有用的方式)。

基本上,将enum 设为子类并将其特征作为EnumSet 传递给您的超类。这样,您仍然可以获得 enums 的所有好处,包括类型安全。

public static class MappedEnum<E extends Enum<E>> extends TreeMap<String, String> {
  public MappedEnum(EnumSet<E> e) {
    // Whatever you like with the set.
  }

  public void method(E e) {
  }

}

public static class Foo extends MappedEnum<Foo.Tables> {
  public enum Tables {
    table1, table2, table3;
  }

  public Foo() {
    super(EnumSet.allOf(Tables.class));
  }

  @Override
  public void method(Foo.Tables e) {
  }

}

您甚至可以使用EnumMap 代替TreeMap 以提高效率。

【讨论】:

  • 看起来很有趣,但似乎不适合这个问题:OP 希望每个枚举条目都有一个 Foo 实例。
  • “我认为你可能试图在枚举中投入太多的智能” - 是的,我真的很喜欢枚举以保证类型安全,在这种情况下,我真的看不出有什么正当理由为什么不能扩展枚举...
  • @AaronDigulla - 这个重构的结果意味着你可以使用MappedEnum&lt;Foo.Tables&gt; tables = ... 然后tables.method(Foo.table1)。它将调用机制由内向外翻转,但您现在拥有更清晰的结构。 PS - 为method 添加了一个E 参数。
  • @OldCurmudgeon:好的,开始说得通了。我现在的主要批评是,这意味着您需要在method() 中进行切换,而不是依赖继承。或者您使用EnumMap 为每个枚举值存储一个处理程序。
  • @AaronDigulla - 根据我的经验,您很少需要特定于枚举的方法,您只需要以某种方式对每个枚举进行分类。您可以通过使枚举实现一个公开其分类的接口来实现这一点。 MappedEnum 然后使用您描述的 Map,但仅用于映射分类。在我看来,使用 caseenums 是一种代码味道。
猜你喜欢
  • 2010-09-21
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-24
  • 1970-01-01
相关资源
最近更新 更多