0

我需要在 Java 中嵌套枚举。但是,在查看 Stackoverflow 和更大的网络时,我发现似乎没有关于嵌套枚举的一般约定。我见过很多不同的解释,但没有一个符合我的需要。

因此,让我从讨论我的要求开始:

我需要枚举来允许命名约定和我的 Java 应用程序中事件类型的简单树类型结构。例如

Event.Draw.Square;
Event.Draw.Circle;
Event.Draw.Triangle;
Event.Draw.Poly;
Event.Draw.Line;

Event.File.Load;
Event.File.Save;

Event.Screen.Zoom;
Event.Screen.Flip;

Event.Ui.New;
Event.Ui.Close;

我将如何在代码中设想这一点,但显然它是不正确的。请提供有关如何使用枚举获取此信息的任何指示?

private enum event
{
    Draw {Square, Circle, Triangle, Poly, Line},
    File {Save, Save_As, Load},
    Screen {Zoom, Flip, Rotate_CW, Rotate_CCW},
    Ui {New_Workspace, Close}   
}

然后我想要一个 case 语句或条件结构能够对 Event.Screen 或 Event.Screen.Zoom 采取行动。例如,请参见以下方法:

public void evenTriggered(Event event)
{
    switch (event)
    {
    case Event.Draw:
            drawEvent(event.Draw);
    case Event.UI:
            uiEvent(event.Ui);
    case Event.Screen:
            screenEvent(event.Screen);
    case Event.File
            fileEvent(event.File);
    default: ;//do nothing

    }//end switch
}//end eventTriggered


public void drawEvent(Event.Draw event)
{

    switch(event.draw)
    {
    case Event.Draw.Square:
            workspace.addSquare();
        break;
    case Event.Draw.Circle:
            workspace.addCircle();
         break;  
    case Event.Draw.Triange:
        workspace.addTriangle();
         break;
     default: ;//do nothing

    };//end switch

}//end drawEvent

感谢您花时间阅读我的帖子,我期待您的建议。

安德鲁。

4

5 回答 5

2

嵌套枚举仅在您也有操作时才有意义is a descendant of。这是您在第一个代码示例中的建议。内置的 Java 枚举实现中没有这样的东西,我看不出它如何适合那里。

但是,您可以自由地使用私有构造函数和public static final实例来实现自己的类似枚举的类,就像我们在enum将 s 添加到 Java 之前所做的那样。有一些警告,比如序列化,但它是可行的。

你也可以这样做:

public enum Foo {

EVENT,
EVENT_DRAW,
EVENT_DRAW_CIRCLE;

public boolean isDescendantOrSelf( Foo other ) {
    return other.name().startsWith( this.name() );
}

}

它并不完美,因为您将无法在 switch/case 语句中使用它们,但它确实为您的平面枚举值提供了基于其名称的树结构。(但不要使用我的实现,它还不够好,我只是想展示这个概念。)

于 2012-04-18T21:35:36.720 回答
1

为什么需要嵌套枚举?在我看来,你正在做的事情是非常反 OOP 的。您应该有一个基类 Event,让 Draw、File、UI 和 Screen 类继承它,然后如果必须(对于 DrawEvent、FileEvent 等),则使用您的枚举最终说明特定事件的类型。另一种选择是静态整数,另一种选择是甚至将“最具体”的事件类型设为另一个类。您将拥有以下内容:

public void drawEvent(DrawEvent event)
{

    switch(DrawEvent.type) // type is of datatype DrawEventType, an enum
    {
    case DrawEventType.Square:
            workspace.addSquare();
            break;
    case DrawEventType.Circle:
            workspace.addCircle();
            break;  
    } //etcetera
}

或使用静态整数:

public void drawEvent(DrawEvent event)
{

    switch(DrawEvent.type) // type is one of the DrawEvent static integers
    {
    case DrawEvent.SQUARE:
            workspace.addSquare();
            break;
    case DrawEvent.CIRCLE:
            workspace.addCircle();
            break;  
    } //etcetera
}
于 2012-04-18T21:31:32.733 回答
0

好的,在收到好的建议后,我相信我有一个可行的解决方案来满足我的要求,我想与你分享。

基本解决方案是创建一个具有两个字段的对象,这两个字段都是枚举。一个是类别,一个是事件。然后我可以为每个类别创建对象的公共静态常量实例,事件配对。通过保持构造函数私有,实例不能在外部创建,因此错误地将选项限制为仅定义为常量和公共的选项。

我现在可以在 EventType 类型中保存任何这些常量实例化。对我来说,这个事件类型将保存在一个 Event 对象中,该对象将与一个中央事件系统一起使用,所有 UI 元素都将注册到该系统以接收应用程序范围的事件通知,例如 redraw()。

public class EventType
{
    public enum EventCategory{Draw, File, Screen, UI};

    public enum Event {Load, Save, Circle, Square, Triangle, Poly, Line, Flip, Zoom, Close,NewWorkspace};

    public final EventType FILE_LOAD = new EventType(EventCategory.File, Event.Load);
    public final EventType FILE_SAVE = new EventType(EventCategory.File, Event.Load);
    public final EventType DRAW_CIRCLE = new EventType{EventCategory.Draw, Event.Circle};
    public final EventType DRAW_SQUARE = new EventType{EventCategory.Draw, Event.Square};
    public final EventType DRAW_TRIANGLE = new EventType{EventCategory.Draw, Event.Triangle};
    public final EventType DRAW_POLY = new EventType{EventCategory.Draw, Event.Poly};
    public final EventType DRAW_LINE = new EventType{EventCategory.Draw, Event.Line};
    public final EventType SCREEN_FLIP = new EventType{EventCategory.Screen, Event.Flip};
    public final EventType SCREEN_ZOOM = new EventType{EventCategory.Screen, Event.zoom};
    public final EventType UI_CLOSE = new EventType{EventCategory.UI, Event.Close};
    public final EventType UI_NEW_WORKSPACE =  new EventType{EventCategory.UI, Event.NewWorkspace};

    public Event event;
    public EventCategory category;

    private EventType(EventCategory cat,  Event evt)
    {
        event = evt;
        category = cat;
    }//end constructor

}//end class 
于 2012-04-19T20:25:31.503 回答
0

你可以做一些类似我对ID3 Java Enum Tree的回答。您可能需要孩子的父指针。

于 2012-04-20T02:35:06.183 回答
0

这可以使用枚举的接口来完成。

public interface Event {
}

public enum Draw implements Event {
  SQUARE, CIRCLE, TRIANGLE, POLY, LINE;
}

public enum File implements Event {
  LOAD, SAVE;
}

public enum Screen implements Event {
  ZOOM, FLIP;
}

public enum Ui implements Event {
  NEW, CLOSE;
}

现在您可以使用以下条件结构对这些枚举事件做出反应:

public void evenTriggered(Event event)
{
  if(event instanceof Draw) {
    drawEvent((Draw)event);
  }
  else if(event instanceof Ui) {
    uiEvent((Ui)event);
  }
  else if(event instanceof Screen) {
    screenEvent((Screen)event);
  }
  else if(event instanceof File) {
    fileEvent((File)event);
  }
  else {
    //do nothing
  }
}//end eventTriggered

public void drawEvent(Draw event)
{

  switch(event)
  {
    case SQUARE:
      workspace.addSquare();
      break;
    case CIRCLE:
      workspace.addCircle();
      break;  
    case TRIANGLE:
      workspace.addTriangle();
      break;
    default: ;//do nothing

  };//end switch

}//end drawEvent
于 2012-06-07T06:34:17.857 回答