如何将我的状态机转换为java?

发布于 2024-10-26 15:05:50 字数 1194 浏览 8 评论 0原文

这是我在 C++ 中执行操作的正常方式:

class object
{
public:
     enum
     {
          STATE_ACTIVE = 0,
          STATE_INACTIVE,

          OBJ_NUM_STATES,
     }

     int   m_State;

     virtual void  UpdateState  ()
     {
           switch(this->m_state)
           {
           case STATE_ACTIVE:    /* do stuff*/    break;
           case STATE_INACTIVE:  /* do stuff*/    break;
           }
     }
}

class SpecialGameObject : public Object
{
public:
    enum
    {
         STATE_SPECIAL_A = OBJ_NUM_STATES + 1,
         STATE_SPECIAL_B,

         SPECIAL_NUM_STATES,
    }

    virtual void UpdateState ()
    {
         Object::UpdateState();

         switch(this->m_State)
         {
         case STATE_ACTIVE:       /* do extra stuff */   break;
         case STATE_SPECIAL_A:    /* do special stuff*/  break;
         case STATE_SPECIAL_B:    /* do special stuff*/  break;
         }
    }
}

我试图找出让所有这些功能在 java 中工作的方法。具体来说,我需要工作:

1)派生类能够具有在派生状态值之后自动排列的状态值。这样我就可以向基类添加新的状态值,而不必担心它们与任何派生类中使用的状态值的范围重叠。

2) 能够在 switch 语句中使用状态值作为 case。

我研究了使用静态最终整数来实现我的状态值。但这些不能用作 case 语句。然后我研究了扩展枚举,但这是不允许的。

有人对我有什么建议吗?

谢谢

Here is the normal way I would do things in C++:

class object
{
public:
     enum
     {
          STATE_ACTIVE = 0,
          STATE_INACTIVE,

          OBJ_NUM_STATES,
     }

     int   m_State;

     virtual void  UpdateState  ()
     {
           switch(this->m_state)
           {
           case STATE_ACTIVE:    /* do stuff*/    break;
           case STATE_INACTIVE:  /* do stuff*/    break;
           }
     }
}

class SpecialGameObject : public Object
{
public:
    enum
    {
         STATE_SPECIAL_A = OBJ_NUM_STATES + 1,
         STATE_SPECIAL_B,

         SPECIAL_NUM_STATES,
    }

    virtual void UpdateState ()
    {
         Object::UpdateState();

         switch(this->m_State)
         {
         case STATE_ACTIVE:       /* do extra stuff */   break;
         case STATE_SPECIAL_A:    /* do special stuff*/  break;
         case STATE_SPECIAL_B:    /* do special stuff*/  break;
         }
    }
}

I am trying to figure out to get all of this functionality to work in java. Specifically I need working:

1) Ability for derived classes to have state values that automatically line up after the derived state values. That way I can add new state values to the base class without worrying about them overlapping the rage of state values used in any of the derived classes.

2) Ability to use the state values as cases in switch statements.

I looked into using static final ints to implement my state values. But those can't be used as case statements. Then I looked into extending enums, but that isn't allowed.

Does anyone have any suggestions for me?

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

挽心 2024-11-02 15:05:50

您需要在 Java 中实现状态模式。这可能对您有帮助。 Wikipedia 还有一个简单易懂的 Java 示例。

You need to implement the state pattern in Java. This might help you. Wikipedia also has a simple and easy to understand example in Java.

只有影子陪我不离不弃 2024-11-02 15:05:50

这足以让你继续前进吗?

final class GameObject {

  enum State { ACTIVE, INACTIVE };

  State state;

  void updateState()
  {
    switch(state) {
      case ACTIVE :
        // update state
        break;
      case INACTIVE:
        // update STATE
        break;
      default:
        assert false : "never get here";
    }
  } 
}

请注意,在 Java 中,enumfinal,因此您不能直接扩展枚举。 (参考这个问题。)如果您确实需要将状态概念扩展到专门的子类中,那么可能足够复杂,您应该考虑使用多态性而不是 switch 语句(另请参阅此处)以获得您想要的东西。或者,您可以将“超级”状态与包装器超类和子类中的专用子状态捆绑在一起,也许可以使用定义的接口。

而且,如果你想严重变形,你可以这样做。 Java 枚举可以实现接口,这非常酷,但我认为这对于您的问题来说是一种使用该功能的特别丑陋的方式......

final class GameObject {

  ActiveStateful state;

  interface ActiveStateful {
    State activeState();
  }

  enum State implements ActiveStateful {
    ACTIVE, INACTIVE;

    public State activeState() {
      return this;
    }
  };

  enum SubState implements ActiveStateful {
    SPECIAL_A(State.ACTIVE), SPECIAL_B(State.ACTIVE);

    SubState(final State activeState) {
      this.activeState = activeState;
    }

    final State activeState;

    public State activeState() {
      return activeState;
    }

  }

}

Is this enough to get you going?

final class GameObject {

  enum State { ACTIVE, INACTIVE };

  State state;

  void updateState()
  {
    switch(state) {
      case ACTIVE :
        // update state
        break;
      case INACTIVE:
        // update STATE
        break;
      default:
        assert false : "never get here";
    }
  } 
}

Note that in Java, enums are final so you can't extend an enum directly. (Reference this SO question.) If you really need to extend the notion of state into specialized subclasses, things are probably complicated enough that you should consider using polymorphism rather than switch statements (see also here) to get what you want. Alternatively, you could bundle the "super" state with specialized substates in a wrapper super- and sub-classes, perhaps with defined interfaces.

And, if you want to get seriously warped, you could do something like this. It's very cool that Java enums can implement interfaces, but I think this counts as a particularly ugly way of using that feature for your question...

final class GameObject {

  ActiveStateful state;

  interface ActiveStateful {
    State activeState();
  }

  enum State implements ActiveStateful {
    ACTIVE, INACTIVE;

    public State activeState() {
      return this;
    }
  };

  enum SubState implements ActiveStateful {
    SPECIAL_A(State.ACTIVE), SPECIAL_B(State.ACTIVE);

    SubState(final State activeState) {
      this.activeState = activeState;
    }

    final State activeState;

    public State activeState() {
      return activeState;
    }

  }

}
胡渣熟男 2024-11-02 15:05:50

但是这些不能用作 case 语句。

如果我告诉你这是不正确的,那就可以解决你的问题,是吗?这是不正确的:您可以打开静态最终 int 常量。

But those can't be used as case statements.

If I told you this was incorrect, that would solve your problems, yes? This is incorrect: you can switch on static final int constants.

殤城〤 2024-11-02 15:05:50

我建议对 switch 语句使用枚举及其序数值。这就是 enum 的诞生目的。

I'd recommend using an enum and its ordinal values for switch statements. That's what enum was born for.

被你宠の有点坏 2024-11-02 15:05:50

请考虑完全摆脱switch。这是一种可怕的憎恶,本应在几十年前停止,但没有。阅读优秀的 “三步(一点)放弃切换”文章了解更多信息。

Please consider getting rid of switch altogether. It is a horrible abomination that should have ceased decades ago but didn’t. Read the excellent “Abandoning switch In Three (And A Bit) Steps” article for more information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文