Java: Могу ли я использовать два разных имени в перечислении как одно и то же? - PullRequest
9 голосов
/ 11 мая 2011

У меня есть перечислимый класс с кардинальными направлениями (Север, Восток, Юг, Запад):

public enum Direction {
    NORTH,
    EAST,
    SOUTH,
    WEST;
}

Есть ли способ использовать несколько имен для одной и той же вещи? Например что-то вроде этого:

public enum Direction {
    NORTH or N,
    EAST or E,
    SOUTH or S,
    WEST or W;
}

На практике я хочу иметь возможность подписывать переменную N или NORTH и иметь две одинаковые операции.

Пример:

Direction direction1=new Direction.NORTH;
Direction direction2=new Direction.N;
//direction1==direction2

Ответы [ 3 ]

10 голосов
/ 11 мая 2011
public enum Direction {
  NORTH,
  EAST,
  SOUTH,
  WEST,
  ;

  // Convenience names.
  public static final Direction N = NORTH;
  public static final Direction E = EAST;
  public static final Direction S = SOUTH;
  public static final Direction W = WEST;
}

допустимо, но "N" не будет работать с автоматически сгенерированным методом valueOf. То есть Direction.valueOf("N") выдаст IllegalArgumentException вместо возврата Direction.NORTH.

Вы также не можете написать case N:. Вы должны использовать полные имена в switch es, значение которых равно Direction.

Кроме этого, сокращенная форма должна работать так же хорошо, как и полная версия. Вы можете использовать Direction.N в EnumSet s, сравнить его на равенство Direction.N == Direction.NORTH, получить его name() (то есть "NORTH"), import static yourpackage.Direction.N; и т. Д.

5 голосов
/ 11 мая 2011

Вы можете сделать что-то вроде этого (Восток и Запад опущены).

public enum Direction {
    NORTH {
        @Override
        Direction getDirection() {
            return NORTH;
        }
    },
    N {
        @Override
        Direction getDirection() {
            return NORTH;
        }
    },
    SOUTH {
        @Override
        Direction getDirection() {
            return SOUTH;
        }
    },
    S {
        @Override
        Direction getDirection() {
            return SOUTH;
        }
    }   ;

    abstract Direction getDirection();
}

Тогда вы могли бы что-то вроде этого

public void foo(Direction arg) {
  Direction d = arg.getDirection();
}

Тогда вы всегда будете иметь дело только с СЕВЕРОМ, ЮГОМ, ВОСТОКОМ и ЗАПАДОМ.

0 голосов
/ 11 мая 2011

Хм, может быть, есть «клиентский Enum» с переменными, которые содержат фактический «значимый Enum»?

public enum Direction {
    NORTH(BaseDirection.NORTH),
    N(BaseDirection.NORTH),
    EAST(BaseDirection.EAST),
    E(BaseDirection.EAST),
    SOUTH(BaseDirection.SOUTH),
    S(BaseDirection.SOUTH),
    WEST(BaseDirection.WEST),
    W(BaseDirection.WEST);

    private BaseDirection baseDirection;

    private Direction(BaseDirection baseDirection) {
        this.baseDirection = baseDirection;
    }

    public BaseDirection getBaseDirection() {
        return baseDirection;
    }           
}

public enum BaseDirection {
    NORTH,
    EAST,
    SOUTH,
    WEST;
}

Какая-то излишняя, но вы можете выставить Direction для клиентского кода и использовать getBaseDirection для реальной логики.

...