Как конвертировать мой конечный автомат в Java? - PullRequest
2 голосов
/ 27 марта 2011

Вот нормальный способ сделать что-то в 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

Я рассмотрел использование статических целочисленных значений для реализации моих значений состояния.Но они не могут быть использованы в качестве заявлений.Затем я посмотрел на расширение перечислений, но это не разрешено.

У кого-нибудь есть предложения для меня?

Спасибо

Ответы [ 5 ]

2 голосов
/ 27 марта 2011

Этого достаточно, чтобы начать работу?

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 enum s равны final, поэтому вы не можете напрямую расширять перечисление.( Ссылка на этот вопрос SO .) Если вам действительно нужно расширить понятие состояния на специализированные подклассы, вещи, вероятно, достаточно сложны, поэтому вы должны рассмотреть , используя полиморфизм, а не операторы 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;
    }

  }

}
2 голосов
/ 27 марта 2011

Вам необходимо реализовать шаблон состояния в Java. Это может помочь вам. Википедия также имеет простой и понятный пример на Java.

1 голос
/ 27 марта 2011

Пожалуйста, рассмотрите возможность избавления от switch в целом. Это ужасная мерзость, которая должна была прекратиться десятилетия назад, но не прекратилась. Прочитайте превосходную статью «Отказ от ответственности» switch в три (и немного) шага » для получения дополнительной информации.

1 голос
/ 27 марта 2011

Но они не могут быть использованы в качестве инструкций.

Если я скажу вам, что это неправильно, это решит ваши проблемы, да?Это неверно: вы можете включить статические финальные int-константы.

1 голос
/ 27 марта 2011

Я бы порекомендовал использовать перечисление и его порядковые значения для операторов switch. Для этого и родился enum.

...