Дженерики перечисления Java

У меня есть класс, как показано ниже,

public class Baseclass {
   private final EmployeeEnum empEnum;
   public Baseclass(EmployeeEnum e) {
       this.empEnum = e;
    }
}

Теперь я хочу сделать базовый класс универсальным и заставить его принимать перечисления определенного типа.

Поскольку Enum не может расширить класс, я создал интерфейс IEnum и сделал EmployeeEnum и ManagerEnum (новое перечисление, которое я создал) для реализации интерфейса.

Я внес изменения в базовый класс, как показано ниже,

public class Baseclass {
   private final Enum<?> empEnum;
   public Baseclass(Enum<?> e) {
       this.empEnum = e;
    }
}

Есть лучший способ сделать это?

Ваше здоровье!!


person mani_nz    schedule 02.12.2015    source источник


Ответы (2)


Если вам просто нужно любое перечисление, вы можете использовать E extends Enum<E>.

public class Baseclass<E extends Enum<E>> {

    private final E e;

    public Baseclass(E e) {
        this.e = e;
    }
}

Все enum расширяют Enum<E>, чтобы они могли наследовать стандартные методы, такие как name и values. Это одна из причин, по которой enums не может расширять другие классы, потому что никакому class в Java не разрешено расширять два класса.

Каждый подкласс должен расширять BaseClass определенным перечислением, подобным этому:

enum MyEnum {

    I, Me, My, Mine;
}

class A extends BaseClass<MyEnum> {

    public A(MyEnum e) {
        super(e);
    }

}

Если вам нужны дополнительные ограничения, такие как создание подклассов, использующих только перечисления специального типа (например, реализация интерфейса), вы можете добавить интерфейс к общему типу следующим образом:

public interface SpecialEnum {

}

enum MyEnum implements SpecialEnum {

    I, Me, My, Mine;
}

enum NotSpecialEnum {

    Am, I, Special;
}

public class BaseClass<E extends Enum<E> & SpecialEnum> {

    private final E e;

    public BaseClass(E e) {
        this.e = e;
    }
}

class A extends BaseClass<MyEnum> {

    public A(MyEnum e) {
        super(e);
    }

}

// This is not allowed.
class B extends BaseClass<NotSpecialEnum> {

    public A(NotSpecialEnum e) {
        super(e);
    }

}

Вы даже можете поместить перечисление внутри расширяющего класса:

class A extends BaseClass<A.AnotherEnum> {

    enum AnotherEnum implements SpecialEnum {

        Hello, All;
    }

    public A(AnotherEnum e) {
        super(e);
    }

}
person OldCurmudgeon    schedule 02.12.2015
comment
Я хочу Enums типа. Как интерфейс IEnum. - person mani_nz; 02.12.2015

Есть лучший способ сделать это?

Лучший способ сделать что? Вы можете изменить приведенный ниже код, который ограничит вас перечислениями, расширяющими IEnum:

class Baseclass<T extends Enum<T> & IEnum> {
    private final T empEnum;
    public Baseclass(T e) {
        empEnum = e;
    }
}

Итак, T extends Enum<T> - T должен быть Enum & - и IEnum - T должен расширять IEnum.

person Michael Lloyd Lee mlk    schedule 02.12.2015
comment
В любом случае, кроме изменения определения класса? Просто изменив подпись конструктора? - person mani_nz; 02.12.2015
comment
Извините, но это не имеет для меня смысла. Почему вы не хотите менять определение класса? - person Michael Lloyd Lee mlk; 02.12.2015
comment
У класса есть другие конструкторы, которые принимают параметры, отличные от Enum. - person mani_nz; 02.12.2015
comment
Ваш ответ помог. Спасибо!! - person mani_nz; 03.12.2015