Заставьте суперкласс использовать Enum, используемый дочерним классом - PullRequest
0 голосов
/ 19 января 2012

У меня есть

public enum BaseActions implements Actions{
    STAND (0,0,0),
    TURN (1,1,1);
    //other stuff
}

public enum CoolActions implements Actions{
   STAND (0,2,3),
   TURN(1,6,9);
   //other stuff
}

public enum LooserActions implements Actions{
   STAND (0,-2,-3),
   TURN(1,-6,-9);
   //other stuff
}

public interface Actions {
       //interface methods
}

class A {
    Actions mCurrentAction;
    protected void notifyNewAction(final Actions pAction, final Directions pDirection){
         //body of the method
    }

    public void doStuff(final Actions pAction) {
         if(pAction.getMyId() > 0)
              notifyNewAction(BaseActions.STAND, myDirection);
         else
             notifyNewAction(BaseActions.TURN, myDirection);
    }
}

class B extends A{
     public void doMyStuff() {
           doStuff(CoolActions.STAND);
     }
}

class C extends A{
     public void doMyStuff() {
           doStuff(LooserActions.STAND);
     }
}

Я хотел бы, чтобы A использовал CoolActions, когда doStuff вызывается из B, и LooserActions, когда вызывается из C. Один из способов, которые я думаю, что я могу сделать, это использовать дженерики,а затем в B и C использовать

doStuff<CoolActions>(CoolActions.STAND)

и иметь в A

public void doStuff<T extends EnumActions&Actions>(final Actions pAction) {
             if(pAction.getMyId() > 0)
                  notifyNewAction(T.STAND, myDirection);
             else
                 notifyNewAction(T.TURN, myDirection);
        }

, где EnumActions является базовым перечислением, которое просто содержит объявление элементов перечисления, и ничего более, что-токак интерфейс для перечислений, но перечисления не могут расширять другой класс, так как они уже расширяют Enum, и интерфейс не может обеспечить то, что я имею в виду.Другой способ - сделать так, чтобы перечисления реализовывали интерфейс EnumActions, который имеет

public interface EnumActions {
    public <T> T getStand();
    public <T> T getTurn();
}

и имеет

 class A {
        Actions mCurrentAction;
        protected void notifyNewAction(final Actions pAction, final Directions pDirection){
             //body of the method
        }

        public <T implements EnumActions> void doStuff(final Actions pAction) {
             if(pAction.getMyId() > 0)
                  notifyNewAction(T.getStand(), myDirection);
             else
                 notifyNewAction(T.getTrun(), myDirection);
        }
    }

и

public enum CoolActions implements Actions, EnumActions{
   STAND (0,2,3),
   TURN(1,6,9);
    public CoolActions getStand();
    public CoolActions getTurn();
   //other stuff
}

class B extends A{
     public void doMyStuff() {
           doStuff<CoolActions>(CoolActions.STAND);
     }
}

Но 1) я нене знаю, сработает ли это 2) я теряю преимущества использования перечислений 3) этот шов - очень плохой способ справиться с этим 4) мне пришлось бы писать много (X полей перечисления на Y различных перечислений).Я изменил со статических полей final на enum, чтобы улучшить читаемость и порядок, и эти швы сделают вещи еще сложнее.

Я проектирую это неправильно?Как я могу справиться с этим?Есть ли предпочтительный способ решения этой проблемы?Спасибо

Ответы [ 2 ]

2 голосов
/ 19 января 2012

Кажется, перечисления ничего не добавляют и не собираются делать то, что вы хотите.Возможно, вам следует использовать обычную иерархию классов - сделать BaseActions, CoolActions и LooserActions просто классами, которые реализуют методы Actions и STAND и TURN в этих классах.

0 голосов
/ 20 января 2012

это некрасиво, но может делать то, что вы хотите:

interface Actions {
    int getMyId();
}
enum BaseActions implements Actions {
    STAND(0, 0, 0), TURN(1, 1, 1);
    BaseActions(int x, int y, int z) {}
    @Override public int getMyId() {
        return 0;
    }
}
enum CoolActions implements Actions {
    STAND(0, 2, 3), TURN(1, 6, 9);
    CoolActions(int x, int y, int z) {}
    @Override public int getMyId() {
        return 0;
    }
}
enum LooserActions implements Actions {
    STAND(0, -2, -3), TURN(1, -6, -9);
    LooserActions(int x, int y, int z) {}
    @Override public int getMyId() {
        return 0;
    }
}
class Directions {}
class A {
    Actions mCurrentAction;
    protected void notifyNewAction(final Actions pAction, final Directions pDirection) {
    System.out.println(pAction+" "+pAction.getClass());
    }
    public void doStuff(final Actions pAction) {
        Directions myDirection = null;
        Enum e=(Enum)pAction;
        if(e instanceof CoolActions)
            e=CoolActions.valueOf(e.name());
        else if(e instanceof LooserActions)
            e=LooserActions.valueOf(e.name());
        if (pAction.getMyId() > 0) notifyNewAction((Actions)e, myDirection);
        else
            notifyNewAction((Actions)e, myDirection);
    }
}
class B extends A {
    public void doMyStuff() {
        doStuff(CoolActions.STAND);
    }
}
class C extends A {
    public void doMyStuff() {
        doStuff(LooserActions.STAND);
    }
}
public class Main {
    public static void main(String[] args) {
        A a = new A();
        a.doStuff(BaseActions.STAND);
        B b = new B();
        b.doMyStuff();
        C c = new C();
        c.doMyStuff();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...