0

Java で列挙型をネストする必要があります。ただし、Stackoverflow とより大きな Web を見回すと、ネストされた列挙型とは何かに関する一般的な規則がないように見えます。さまざまな解釈を見てきましたが、私のニーズに合ったものはありません。

それでは、私の要件について説明することから始めましょう。

命名規則を許可する列挙型と、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}   
}

次に、ケース ステートメントまたは条件付き構造が、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列挙型実装にはそのようなものはなく、それがどのようにそこに収まるかはわかりません。

ただし、 sがJavaに追加されるpublic static final前に行ったように、プライベートコンストラクターとインスタンスを使用して、独自の列挙型のようなクラスを自由に実装できます。enumシリアル化のようないくつかの注意点がありますが、それは実行可能です。

これを行うこともできます:

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 などの場合)。もう 1 つのオプションは static int です。さらに別のオプションは、「最も具体的な」イベント タイプを別のクラスにすることです。次のようになります。

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

これは、列挙型のインターフェイスを使用して実現できます。

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 に答える
0

良いアドバイスを受け取った後、私は自分の要件に対する実行可能な解決策があると信じています。それをあなたと共有したいと思います.

基本的な解決策は、両方とも列挙型である 2 つのフィールドを持つオブジェクトを作成することです。1 つはカテゴリ、もう 1 つはイベントです。次に、各カテゴリ、イベントの組み合わせについて、オブジェクトの public static 定数インスタンスを作成できます。コンストラクターを非公開にしておくと、インスタンスを外部で作成できなくなり、オプションが定数およびパブリックとして定義されたものだけに制限されてしまいます。

これらの定数のインスタンス化を EventType の型に保持できるようになりました。私にとって、このイベント タイプは、すべての UI 要素が redraw() などのアプリケーション全体のイベント通知を受け取るために登録される中央イベント システムと共に使用される Event オブジェクトに保持されます。

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 に答える