Как реализовать интерфейс с перечислением, в котором интерфейс расширяет Comparable?

Рассмотрим этот код:

public interface Foo extends Comparable<Foo> {}

public enum FooImpl implements Foo {}

Из-за ограничений стирания типа я получаю следующую ошибку:

java.lang.Comparable нельзя наследовать с разными аргументами: <Foo> и <FooImpl>

У меня следующие требования:

  • FooImpl должно быть перечислением, потому что мне нужно использовать его как значение по умолчанию в аннотациях.
  • Контракт моего интерфейса в том, что он должен быть сопоставимым.

Я уже пробовал использовать общие границы в интерфейсе, но это не поддерживается в Java.


person soc    schedule 23.08.2011    source источник
comment
Попробуйте public interface Foo public enum FooImpl implements Foo, Comparable<FooImpl> {...}   -  person Eran Zimmerman Gonen    schedule 23.08.2011
comment
Проблема в том, что FooImpl уже реализует Comparable<FooImpl>.   -  person soc    schedule 23.08.2011
comment
И вы просто хотите показать, что это так? Напишите это в комментарии.   -  person Eran Zimmerman Gonen    schedule 23.08.2011
comment
Мне нужно обрабатывать экземпляры Role как Comparable, комментарий здесь не поможет.   -  person soc    schedule 23.08.2011
comment
Чуть выше public enum... добавить: //Note: implements Comparable.   -  person Eran Zimmerman Gonen    schedule 23.08.2011
comment
Думаю, компилятор проигнорирует этот комментарий ...   -  person soc    schedule 23.08.2011
comment
@soc позвольте нам продолжить обсуждение в чате   -  person Eran Zimmerman Gonen    schedule 23.08.2011
comment
только для записи FooImpl - это ужасная практика именования.   -  person    schedule 23.08.2011
comment
@Jarrod, доводя ваш пост в блоге до логического завершения: если у меня есть только одна реализация интерфейса Truck, ничем не выделяющаяся, у меня должен быть просто класс Truck (предположительно в другом пакете). Избыточность - не грех, когда дело доходит до того, чтобы люди могли быстро понять дизайн. Тот факт, что IDE предоставляют значки для обозначения интерфейсов, не является хорошей причиной НЕ различать их в противном случае. Я не удивлен, что вам пришлось закрыть комментарии.   -  person Ed Staub    schedule 23.08.2011
comment
@Ed Я закрыл комментарии по причинам, связанным со спамом, и, к вашему мнению, тот факт, что в Java вы говорите public interface XXX и public class YYY inherits XXX, уже достаточно отличим от того, что что-то является Interface. Если вы не можете быстро понять, что XXX - это интерфейс непосредственно из кода, вам, вероятно, не следует владеть клавиатурой.   -  person    schedule 23.08.2011
comment
@Jarrod, вы должны попробовать опубликовать свое мнение по этому поводу на programmers.stackexchange.com. Таким образом вы можете получить другие данные, не беспокоясь о спаме. Возможно, вы захотите приглушить, и если вы не согласны со мной, вы идиотка, хотя - это плохо работает.   -  person Ed Staub    schedule 23.08.2011


Ответы (3)


Перечисления реализуют Comparable, поэтому FooImpl дважды расширяет Comparable несовместимыми аргументами.

Следующее будет работать:

public interface Foo<SelfType extends Foo<SelfType>> extends Comparable<SelfType> { ... }

public enum FooImpl implements Foo<FooImpl> { ... }
person jvdneste    schedule 23.08.2011
comment
достаточно public interface Foo<SelfType> extends Comparable<SelfType> - person newacct; 19.11.2013

Enum уже реализует сопоставимый, поэтому вы не могу отменить это.

Общий ответ относительно почему-бы-ан-перечисление-реализовать-интерфейс < / а>.

person NimChimpsky    schedule 23.08.2011
comment
Вы избегаете вопроса. Что, если бы это был другой интерфейс. - person aioobe; 23.08.2011
comment
@aioobe да? Вопрос спрашивает, как реализовать интерфейс, расширяющий сопоставимые - person NimChimpsky; 23.08.2011
comment
Если я хочу обратиться к моему объекту перечисления через свой интерфейс: (Interface Foo {...} Enum1 implements Foo {...} Foo x1 = Enum1.FIRST;) и если мне также нужно использовать его в контексте, требующем Comparable, то я должен объявить, что Foo extends Comparable<??something??>. Без (по общему признанию неуклюжего) ввода ответа @ jvdnese у вас не может быть двух разных Enum, реализующих Foo, и пусть компилятор знает, что Foos Comparable. (Это всего лишь предупреждение, так что вы можете просто пропустить implements Comparable). Пример с предупреждением: TreeSet<Foo> x = new TreeSet<>(); - person Joshua Goldberg; 15.07.2020

На самом деле вы получите следующую ошибку:

Интерфейс Comparable нельзя реализовать более одного раза с разными аргументами: Comparable<FooImpl> и Comparable<Foo>

Поскольку enum FooImpl уже реализует Comparable<FooImpl> неявно, вы не можете переопределить его снова как Comparable<Foo>.

person ramsharma    schedule 16.11.2013