Переопределение сравнения с расширенным классом — что происходит?

Я пытался переопределить compareTo таким образом: это оригинал:

@Override
public int compareTo(ProductPart6 s)
{
    return this.getproductName().compareTo(s.getproductName());

}

это то, что я пытаюсь переопределить: он выдает ошибку. Метод compareTo (SubClass) типа SubClass должен переопределять или реализовывать метод супертипа.

@Override
    public int compareTo(SubClass s)
    {
        return this.getTitle().compareTo(s.getTitle());

    }

Я думаю, что это очень неправильно. Мой ProductPart6 не имеет getTitle(), и это вызывает его

@Override
    public int compareTo(ProductPart6 s)
    {
        return this.getTitle().compareTo(s.getTitle());

    }

чтобы выдать ошибку (getTitle() не определен для типа ProductPart6) - если бы я определил его там, не было бы смысла переопределять его. Что я делаю неправильно? У меня есть SubClass, расширяющий ProductPart6, и ProductPart6 реализует Comparable - я думал, что смогу реализовать его в SubClass, но нет. Это было невозможно.


person user2391210    schedule 25.11.2013    source источник
comment
У вас есть общие параметры типа, объявленные при реализации Comparable в суперклассе?   -  person ATG    schedule 26.11.2013
comment
Зачем тебе @Override?   -  person hichris123    schedule 26.11.2013
comment
Я бросил туда переопределение в надежде, что это исправит. ржу не могу. У меня нет объявленных параметров универсального типа. Я посмотрю на это. Спасибо за совет.   -  person user2391210    schedule 26.11.2013


Ответы (2)


Когда класс реализует Comparable<T>, вы должны указать тип объекта (T), с которым можно сравнивать экземпляры вашего класса. Все подреализации compareTo также должны принимать параметр того же типа, T.

Рассмотрим два класса:

public class Alpha implements Comparable<Alpha> {
    @Override
    public int compareTo(Alpha a) {
        ...
    }
}

и...

public class Bravo extends Alpha {...}

Если вы попытаетесь переопределить compareTo в Bravo, вы должны предоставить параметр типа Alpha, потому что Alpha — это тип, который удовлетворяет T в объявлении класса (где implements Comparable включено). В противном случае он не переопределит метод супертипа, и поэтому компилятор жалуется на аннотацию @Override, которую вы видите здесь.

В вашем случае, я думаю, вам нужно подумать, достаточно ли совместимы ProductPart6 и SubClass, чтобы их можно было использовать таким образом. Если нет, рассмотрите возможность использования отдельных экземпляров Comparator или рефакторинга для создания общего типа, который удовлетворит T в обоих случаях.

person ATG    schedule 25.11.2013

Чтобы расширить ответ @ATG: если у вас есть этот класс:

public class Alpha implements Comparable<Alpha> {
    @Override
    public int compareTo(Alpha a) {
        ...
    }
}

вы можете использовать этот класс в контекстах, требующих Comparable, таких как SortedSet<Alpha>. Но когда у вас есть SortedSet<Alpha>, элементы набора могут относиться к классу Alpha или любому подклассу, включая Bravo:

public class Bravo extends Alpha {...}

Поскольку в наборе могут быть объекты как Alpha, так и Bravo, операции над наборами должны иметь возможность сравнивать объекты одного типа с объектами другого в любом порядке. Это может позвонить

A.compare(B);

где A — это Alpha, а B — это Bravo. Это вызовет метод compareTo, который вы написали в Alpha. Это также может вызвать

B.compare(A);

где снова A — это Alpha, а B — это Bravo. Вот почему неправильно объявлять

@Override
public int compareTo(Bravo b) { ... }

в классе Bravo, потому что это предотвратило бы вызов B.compare(A). Вам нужно не только объявить это так:

@Override
public int compareTo(Alpha a) { ... }

он также должен работать правильно, когда вызывается с Bravo и Alpha. Кроме того, метод в Alpha должен работать правильно, когда его параметром является Bravo, и эффект должен заключаться в том, что compareTo дает вам правильный общий порядок, независимо от того, какая комбинация типов передается ему.

Если вы хотите, чтобы каждый массив или коллекция содержали только объекты с классом Alpha или только объекты с классом Bravo, вам понадобится какой-то другой механизм, гарантирующий, что все относится к одному классу, иначе не используйте подкласс вообще (это то, к чему, я думаю, @ATG имел ввиду).

person ajb    schedule 26.11.2013