Почему невозможно реализовать Comparable<T> несколько раз?
Кажется, вы обычно реализуете java.lang.Comparable
интерфейс без указания параметра типа.
public abstract class Area implements Comparable {
@Override
public int compareTo(Object other) {
if (other instanceof Area)
return new Double(getArea()).compareTo(other.getArea());
return -1; // or something else
}
abstract public double getArea();
}
Поскольку я хочу сравнить только яблоки с яблоками, думаю, имеет смысл указать тип.
public abstract class Area implements Comparable<Area> {
@Override
public int compareTo(Area other) {
// ...
Если я хочу ввести другой класс для сравнения Area
с, я думал, что мог бы сделать следующее:
public abstract class Area implements Comparable<Area>, Comparable<Volume> {
@Override
public int compareTo(Area other) {
// ...
}
@Override
public int compareTo(Volume other) {
// ...
}
}
Но компилятор Java говорит мне:
Area.java:2: error: repeated interface
public abstract class Area implements Comparable<Area>, Comparable<Volume> {
^
Area.java:2: error: Comparable cannot be inherited with different arguments: <Area> and <Volume>
- Есть ли недостатки, указывающие аргумент типа для универсального интерфейса?
- Почему Java не позволяет мне эту множественную реализацию?
Примечание: я использую версию Java 1.7.0_45
2 ответа
Нет, это не недостаток в определении общего - это на самом деле функция. Кроме того, я не помню ни одного недостатка использования обобщенных элементов в интерфейсах, кроме общеизвестного факта, что вы не можете создать экземпляр обобщенного типа или создать универсальный массив (но это больше проблема реализации, а не самого интерфейса).
Это из-за стирания типа.
Comparable<Area>
а такжеComparable<Volume>
по сути тот же класс для виртуальной машины и вскоре после проверки правильности также для компилятора.
Если вы хотите реализовать два разных сопоставимых интерфейса, просто используйте Comparator
Для них - как правило, легче поддерживать композицию, чем наследование в классах.
В некоторых приложениях (различая дженерики во время выполнения) вы также можете попытаться разделить их на подклассы, например: ComparableArea extends Comparable<Area>
& ComparableVolume extends Comparable<Volume>
, но это, в данном конкретном случае, вызовет больше проблем, чем решит ИМО, так как вы все равно получите Comparable cannot be inherited with different arguments
ошибка - но по крайней мере вы могли бы дифференцировать эти интерфейсы, например, instanceof
,
Я думаю, что таким образом java говорит, что связанные классы могут быть Comparable, но используя искусственный Comparator, мы можем сделать больше сравнений между несвязанными классами. Таким образом, мы должны реализовать общий интерфейс связанных классов (классов в пределах одной иерархии наследования). В случае, если мы хотим добавить искусственную реализацию, добавьте интерфейс, через который можно проходить (так же есть пара семейств интерфейсов, таких как Comparable и Comparator).