Сопоставимая ошибка

Вопрос новичка здесь. Я пытаюсь учить себя, и иногда одиночный маршрут может разочаровывать. Я работаю над проблемой в книге Ляна «Введение в программирование на Java», 8-е издание (упражнение 14.1), где мне нужно изменить класс GeometricObject для реализации Comparable, а затем определить статический метод «max», чтобы найти больший из двух GeometricObjects. Затем я должен написать тестовую программу, которая использует этот метод max для нахождения большего из двух прямоугольников. Ранее в книге автор предлагал нам создать подкласс Rectangle, расширяющий класс GeometricObject. Я изменил класс GeometricObject для реализации Comparable и создал метод max. Затем я изменил подкласс Rectangle, чтобы он также реализовывал Comparable. Я также написал тестовую программу.

Но Eclipse дает мне большой красный крестик в объявлении моего класса Rectangle, в котором говорится: «Интерфейс Comparable не может быть реализован более одного раза с разными аргументами: Comparable и Comparable». Вот когда мое объявление класса выглядит так:

public class Rectangle extends GeometricObject implements Comparable<Rectangle> {

Я попытался полностью удалить параметр:

public class Rectangle extends GeometricObject implements Comparable {

... и сообщение об ошибке меняется на «Comparable — необработанный тип. Ссылки на универсальный тип Comparable должны быть параметризованы». Кроме того, в этом случае добавляется вторая ошибка: «Тип Rectangle должен реализовывать унаследованный абстрактный метод Comparable.compareTo(Object)».

Когда я смотрю на примеры такого рода объявлений, кажется, что они всегда используют имя класса в качестве параметра для Comparable в объявлении, и на самом деле это то, что написано в книгах. Так почему здесь написано, что я не могу этого сделать?

А как насчет второй ошибки, связанной с методом compareTo()? Почему это указывается только тогда, когда я удаляю параметр из объявления? Далее следует код для класса Rectangle (если мне нужно, я также могу опубликовать суперкласс GeometricObject):

public class Rectangle extends GeometricObject implements Comparable<Rectangle> {
private double width;
private double height;

public Rectangle() {
}

public Rectangle(double width, double height) {
    this.width = width;
    this.height = height;
}

public Rectangle(double width, double height, String color, boolean filled) {
    this.width = width;
    this.height = height;
    setColor(color);
    setFilled(filled);
}

public double getWidth() {
    return width;
}

public void setWidth(double width) {
    this.width = width;
}

public double getHeight() {
    return height;
}

public void setHeight(double height) {
    this.height = height;
}

public double getArea() {
    return width * height;
}

public double getPerimeter() {
    return 2 * (width + height);
}

/** Implement the compareTo method defined in Comparable */
public int compareTo(Rectangle o) {
    if (getArea() > ((Rectangle)o).getArea())
        return 1;
    else if (getArea() < ((Rectangle)o).getArea())
        return -1;
    else
        return 0;
}

}

person Kyle Walker    schedule 30.03.2012    source источник
comment
Какие свойства/методы доступны на GeometricObject? Я думаю, что идея заключается в том, что вы реализуете Comparable только в целом на самом GeometricObject таким образом, чтобы все подклассы также работали.   -  person mellamokb    schedule 30.03.2012
comment
Упс. Эта первая ошибка на самом деле гласит: Интерфейс Comparable не может быть реализован более одного раза с разными аргументами: Comparable и Comparable‹Rectangle›   -  person Kyle Walker    schedule 30.03.2012
comment
Реализует ли GeometricObject Comparable?   -  person Eric Grunzke    schedule 30.03.2012
comment
См. stackoverflow.com/questions/8039844/ например.   -  person mellamokb    schedule 30.03.2012
comment
открытый абстрактный класс GeometricObject реализует Comparable { private String color = white; закрытое логическое значение заполнено; private java.util.Date dateCreated;....... далее следует код..   -  person Kyle Walker    schedule 30.03.2012
comment
Извините, я тоже новичок в StackOverflow и пытаюсь понять, как форматировать код в этих комментариях. Я только что опубликовал первую часть класса GeometricObject. Надеюсь, понятно, что я реализовал Comparable и в этом классе.   -  person Kyle Walker    schedule 30.03.2012
comment
Код в комментариях не будет работать очень хорошо. Однако вы можете отредактировать свой вопрос, добавив туда код GeometricObject.   -  person Eric Grunzke    schedule 30.03.2012
comment
Понятно! Спасибо вам всем. Решение заключалось в том, чтобы оставить компьютер и вывести своих кошек на улицу на солнце на несколько минут, думая о проблеме и всех ваших отзывах. Я слишком усложнял весь интерфейс Comparable. На самом деле Comparable — это просто ПРОСТОЙ интерфейс с одним методом, который необходимо переопределить. Как только я понял эту концепцию, я смог вернуться к коду, и запутанные ошибки действительно выделялись. В книге, которую я использую, еще не описаны дженерики, так что это сбивает с толку. Еще раз спасибо всем вам!   -  person Kyle Walker    schedule 30.03.2012
comment
Рад, что это исправлено. Не забывайте голосовать/принимать комментарии/ответы, которые помогли вам, чтобы будущие пользователи, которые увидят этот вопрос, могли получить хорошее представление о решении!   -  person Eric Grunzke    schedule 31.03.2012
comment
Стек пока не позволяет мне проголосовать, потому что у меня низкий рейтинг 6. В нем сказано, что мне нужно набрать 15 баллов, прежде чем я смогу проголосовать :-( Но я думаю, что это позволит мне принять.   -  person Kyle Walker    schedule 02.04.2012
comment
Похоже, одна из вещей, которые я делал неправильно, заключалась в том, что я помещал фактический объект класса в качестве параметра метода compareTo. Когда я просто сделал параметр (Object o), он сработал.   -  person Kyle Walker    schedule 02.04.2012


Ответы (2)


Да, это немного сложно и может сбивать с толку.

Когда вы объявляете GeometricObject как Comparable, это означает, что каждый GeometricObject можно сравнивать с другим GeometricObject, поэтому вы можете сортировать список GeometricObject (вероятно, это будут экземпляры его подклассов, потому что он, вероятно, будет абстрактным). Поэтому, когда вы реализуете Comparable в GeometricObject, вам нужно реализовать эту функцию:

public int compareTo(GeometricObject o) {}

в этот момент при расширении GeometricObject с помощью Rectangle-Rectangle автоматически выводится метод суперкласса compareTo. и при реализации Comparable в Rectangle вам необходимо реализовать эту функцию:

public int compareTo(Rectangle o) {}

Кажется, что нет никаких проблем, потому что это похоже на обычную перегрузку, но вот в чем загвоздка — дженерики в Java — это просто синтаксический сахар для компилятора — во время выполнения все дженерики становятся объектами, поэтому после компиляции Rectangle будет содержать 2 метода, которые будет то же самое.

Таким образом, у вас есть выбор только одного, хотя, если мы возьмем ваш вариант использования, это, вероятно, нормально - вы можете реализовать только Comparable в суперклассе, а в Rectangle переопределить его и проверить, является ли он экземпляром Rectangle и выполнять вашу конкретную логику или использовать логику суперкласса.

person shem    schedule 30.03.2012

Поскольку геометрический объект родительского класса уже реализует Comparable, вам не нужно снова реализовывать то же самое в базовом классе «Прямоугольник».

Ваш базовый класс должен выглядеть так

public class Rectangle extends geometricObject { }

Поскольку геометрический объект реализует Comparable, даже класс прямоугольника реализует Comparable. Вам просто нужно переопределить метод compareTo() в классе прямоугольника для сравнения с использованием метода max.

person Pratik Shelar    schedule 30.03.2012
comment
Итак, я удалил реализацию Comparable из объекта Rectangle. В конце программы я переопределил метод compareTo(). Но это не признание того, что я это сделал. Eclipse помечает мое объявление класса ошибкой, которая говорит мне, что я должен переопределить compareTo(). Я переопределяю это неправильно? - person Kyle Walker; 30.03.2012
comment
Быстрый совет: В подобных ситуациях вы можете использовать функцию Eclipe Quickfix: поместите курсор на имя класса (Eclipse пометит его красной пунктирной линией) и нажмите CTRL+1 в Windows или CMD+1 в OSX. Eclispe покажет всплывающее окно с несколькими предложениями (в зависимости от типа ошибки). В вашем случае вы должны выбрать Добавить нереализованные методы. Eclipse добавит отсутствующие методы, и вы сможете проверить, чем их сигнатура отличается от того, что вы написали сами. Может быть, это поможет что-то выяснить. - person Stefan; 31.03.2012