Реализация Сопоставимый с общим классом
Я хочу определить класс, реализующий общий интерфейс Comparable. В то время как в моем классе я также определил элемент типового типа T
. Чтобы реализовать интерфейс, я делегирую сравнение T
. Вот мой код:
public class Item<T extends Comparable<T>> implements Comparable<Item> {
private int s;
private T t;
public T getT() {
return t;
}
@Override
public int compareTo(Item o) {
return getT().compareTo(o.getT());
}
}
Когда я пытаюсь скомпилировать его, я получаю следующую информацию об ошибке:
Item.java:11: error: method compareTo in interface Comparable<T#2> cannot be applied to given types;
return getT().compareTo(o.getT());
^
required: T#1
found: Comparable
reason: actual argument Comparable cannot be converted to T#1 by method invocation conversion
where T#1,T#2 are type-variables:
T#1 extends Comparable<T#1> declared in class Item
T#2 extends Object declared in interface Comparable
1 error
Может ли кто-нибудь сказать мне, почему и как его исправить?
Ответы
Ответ 1
В основном компилятор не может доказать, что общий тип o
является тем же самым T
, что и тип this
.
Например, я мог бы сделать следующее:
new Item<String>().compareTo(new Item<Integer>());
Это явно неправильно и является сценарием, который предотвращает компилятор. Я думаю, вам просто нужно удалить необработанные типы:
public class Item<T extends Comparable<T>>
implements Comparable<Item<T>> {
...
@Override
public int compareTo(Item<T> o) {
return getT().compareTo(o.getT());
}
}
Ответ 2
Вы используете необработанные типы в определении класса (Item<T>
является общим, но вы опускаете параметр типа <T>
), измените его на:
class Item<T extends Comparable<T>> implements Comparable<Item<T>>
(Обратите внимание на последний <T>
)
Затем должен быть также изменен метод compareTo
:
public int compareTo(Item<T> o) { // again, use generics
return getT().compareTo(o.getT());
}
Ответ 3
Думаю, это имеет смысл. Я собрал и протестировал следующее:
class Item<E extends Comparable<E>> implements Comparable<E> {
private int s;
private E t;
public E getE() {
return t;
}
@Override
public int compareTo(E e) {
return getE().compareTo(e);
}
public int compareTo(Item<E> other)
{
return getE().compareTo(other.getE());
}
}
Обратите внимание, что теперь вам нужно иметь два метода compareTo.