Reputation: 63
I've been trying to override a compareTo in such a way: This is the original:
@Override
public int compareTo(ProductPart6 s)
{
return this.getproductName().compareTo(s.getproductName());
}
this is what i'm trying to override it with: it throws an error The method compareTo(SubClass) of type SubClass must override or implement a supertype method.
@Override
public int compareTo(SubClass s)
{
return this.getTitle().compareTo(s.getTitle());
}
I'm thinking this is very wrong. My ProductPart6 doesn't have a getTitle() and that causes it
@Override
public int compareTo(ProductPart6 s)
{
return this.getTitle().compareTo(s.getTitle());
}
to throw an error (getTitle() is undefined for the type ProductPart6) - if I defined it there there'd be no point overriding it. What am I doing wrong? I have the SubClass extending ProductPart6 and ProductPart6 implements Comparable - I thought I could implement it on SubClass, but no. That was a no go.
Upvotes: 6
Views: 4958
Reputation: 31699
To expand on @ATG's answer: If you have this class:
public class Alpha implements Comparable<Alpha> {
@Override
public int compareTo(Alpha a) {
...
}
}
you can use this class in contexts that require Comparable
, such as SortedSet<Alpha>
. But when you have a SortedSet<Alpha>
, the elements of the set can be of class Alpha
or any subclass, including Bravo
:
public class Bravo extends Alpha {...}
Since the set can have both objects of type Alpha
and Bravo
in it, the set operations need the ability to compare objects of one type with that of the other, in either order. It might call
A.compare(B);
where A
is an Alpha
and B
is a Bravo
. This will call the compareTo
method you wrote in Alpha
. It might also call
B.compare(A);
where again A
is an Alpha
and B
is a Bravo
. That's why it's wrong to declare
@Override
public int compareTo(Bravo b) { ... }
in the Bravo
class, because this would prevent B.compare(A)
from being called. Not only do you need to declare it like this:
@Override
public int compareTo(Alpha a) { ... }
it also has to work right when it's called with a Bravo
and an Alpha
. Also, the method in Alpha
must work right when its parameter is a Bravo
, and the effect has to be that compareTo
gives you a proper total ordering no matter which combination of types is passed to it.
If your intent is that each array or collection will contain only objects whose class is Alpha
, or only objects whose class is Bravo
, you'd need some other mechanism to ensure that everything is the same class, or else don't use a subclass at all (which is what I think @ATG was getting at).
Upvotes: 4
Reputation: 1707
When a class implements Comparable<T>
you have to specify the type of object (T
) against which instances of your class can be compared. All sub-implementations of compareTo
must also accept the same type parameter, T
.
Let's consider two classes:
public class Alpha implements Comparable<Alpha> {
@Override
public int compareTo(Alpha a) {
...
}
}
and...
public class Bravo extends Alpha {...}
If you try to override compareTo
in Bravo
you must provide a parameter of type Alpha
because Alpha
is the type that satisfies T
in the class declaration (where implements Comparable
is included). Otherwise, it won't override the supertype method and thus the compiler complains about the @Override
annotation, which is what you're seeing here.
In your case, I think you need to consider whether ProductPart6
and SubClass
are compatible enough to be used in this way. If not, consider using separate Comparator
instances instead or refactoring to create a common type that will satisfy T
in both cases.
Upvotes: 5