2013-02-20 94 views
4

如果我有一堆类都包含一个Enum和EnumMap,我想为这些类创建一个超类。创建一个通用类型的EnumMap枚举

public interface ColorEnum { 
} 

class ColorMarbles extends Toy { 
    enum MARBLE implements ColorEnum 
     { BLUE, GREEN } 
    EnumMap<MARBLE, String> names = new EnumMap<MARBLE, String>(MARBLE.class); 
    //stuff 
    // fields 

    public void populate(ArrayList<String> designer) { 
     int i = 0; 
     for(MARBLE marble : MARBLE.values()) { 
      marble.name = designer.get(i); 
      i++; 
     } 
    } 
} 

class ColorBalloons extends Toy { 
    enum BALLOON implements ColorEnum 
     { YELLOW, RED } 
    EnumMap<BALLOON, String> names = new EnumMap<BALLOON, String>(BALLOON.class); 
    //stuff 
    // fields 

    public void populate(ArrayList<String> designer) { 
     int i = 0; 
     for(BALLOON balloon : BALLOON.values()) { 
      balloon.name = designer.get(i); 
      i++; 
     } 
    } 
} 

如何使创建一个超类具有泛型EnumMap,其中包含ColorEnum类型的枚举像这样?

public abstract class Toy { 
    EnumMap<ColorEnum, String> names; 
} 

eidt:我意识到我对我的例子太模糊了。狗可能是一个坏榜样。我把它改成希望更清楚的东西。

我所拥有的是一堆类,其中包含填充EnumMap的填充方法。名称按照预定义的顺序排列。我希望能够将它带入Toy超类,而不是在每个新类类型的Toy中都复制粘贴。

希望这将解释更多我在找什么。

+0

我不确定你在做什么。你能把它清理一下吗? – 2013-02-20 16:13:28

+0

为什么不简单地使用HashMap? EnumMap只是一个针对枚举的优化实现。 – 2013-02-20 16:15:40

+0

我仍然无法在这里清楚地看到这个意图。在哪里和谁被实际称为'populate()'方法?他们为什么不能简单地静止?你是否期望在运行时使用不同的值多次调用它们(从而更改名称)?大理石和气球的“设计师”名单是否相同,这意味着蓝色大理石和黄色气球具有相同的名称或完全不相关?对不起,有这么多问题,但我仍然不明白为什么简单的枚举方法不能在这里工作。 :) – Natix 2013-02-20 17:09:52

回答

5

我有一种感觉,你的设计不必要的过于复杂。

使用枚举

如果你不需要一个类继承,你可以用枚举工作直接与顶级类。

public interface Animal {} 

public enum Dog implements Animal { 
    HUSKY("Husky"), LAB("Labrador"); 

    private final String name; 

    Dog(String name) { 
     this.name = name; 
    } 

    public String getName() { 
     return name; 
    } 
} 

枚举可以像任何其他Java类一样声明字段,方法和实现接口。他们唯一的限制是他们的直接超类总是java.lang.Enum,他们不能被扩展。

但是每个枚举常量都可以拥有自己的一组传递给它的构造函数的唯一数据。甚至有可能每个常量都可以通过其独特的实现覆盖该枚举的常见方法。

一个很好的教程解释更多关于枚举的全功率: http://javarevisited.blogspot.cz/2011/08/enum-in-java-example-tutorial.html


不枚举

如果你需要一个实际的类继承从共享一些通用的方法(例如Animal超类),我仍然会放弃地图方法,而是尝试更多面向对象的操作:

public class Animal { 
} 

public abstract class Dog extends Animal { 

    public abstract String getName(); 

    public static class Husky extends Dog { 
     @Override 
     public String getName() { 
      return "husky"; 
     } 
    } 

    public static class Lab extends Dog { 
     @Override 
     public String getName() { 
      return "labrador"; 
     } 
    } 

} 
+2

您也可以将'getName()'推送到接口。 – Zutty 2013-02-20 16:21:59

+0

我在每个类中都有完全相同的方法,并且细化了所有我想创建可以容纳所有泛型方法的抽象超类的类。但要做到这一点,我需要访问EnumMap。 – Aboutblank 2013-02-20 16:27:34

+0

也许我实际上并没有帮助你解决问题,但这是我可以从你的狗的名字中得到的所有东西。也许你应该让你的问题更具体地说明你想要达到的目标。 – Natix 2013-02-20 16:39:54

1

我用于这种事情的一种机制是扩展一个通用基类,它具有一个通用参数,允许您将Enum的详细信息传递给它。

这个例子定义了一个基础Table类数据库表:

public class Table<Column extends Enum<? extends Column>> { 
    // Name of the table. 
    protected final String tableName; 
    // All of the columns in the table. This is actually an EnumSet so very efficient. 
    protected final Set<Column> columns; 

    /** 
    * The base interface for all Column enums. 
    */ 
    public interface Columns { 
    // What type does it have in the database? 
    public Type getType(); 
    } 

    // Small list of database types. 
    public enum Type { 
    String, Number, Date; 
    } 

    public Table(String tableName, 
       Set<Column> columns) { 
    this.tableName = tableName; 
    this.columns = columns; 
    } 

} 

现在你可以继承这一点:

public class VersionTable extends Table<VersionTable.Column> { 

    public enum Column implements Table.Columns { 
    Version(Table.Type.String), 
    ReleaseDate(Table.Type.Date); 

    // Sadly all of this must be in ALL of your enums but most of the work can be pushed up to `Table` 
    final Table.Type type; 

    Column(Table.Type type) { 
     this.type = type; 
    } 

    @Override 
    public Type getType() { 
     return type; 
    } 
    } 

    public VersionTable() { 
    super("Versions", EnumSet.allOf(Column.class)); 
    } 
} 

,并在处理您的枚举父类使用功能。

请注意,我将EnumSet传递给Table构造函数。如果您决定EnumSet不足,我相信您可以更改此以适应您的EnumMap要求。

+0

一个聪明的模式,但我有点关心类型命名:'Columns'是'Table'中的嵌套接口,其中'Column'是范围中定义的类型变量通用Table类的类。为了避免混淆,我会将声明更改为'class Table >'。 – Natix 2013-02-20 16:47:14

+0

@Natix - 虽然我很长时间并且很难确定命名,并且考虑了当前通用类型的单字母大写字母的方法。通过一切手段选择你喜欢的任何命名约定。在我使用大约十几张表格的环境中,“列”/“列”对我来说最自然,并且没有混淆。很明显,你会看到强大的类型检查的巨大好处,同时仍然只能编写大部分的样板代码。 – OldCurmudgeon 2013-02-20 22:31:54

相关问题