问题
For fun I'm creating a sorting framework to better understand the various sorting algorithms. And, I'm trying to make it generic enough so that it can sort anything that implements an interface that extends the comparable interface. However, the java compiler isn't happy with me.
Here's my interface:
public interface Sorter<C extends Comparable<C>>
{
void sort(C[] comparables);
void sort(C[] comparables, Comparator<C> comparator);
}
And, here's my abstract class that implements that interface:
public abstract class AbstractSort<C extends Comparable<C>> implements Sorter
{
protected abstract void doSort(C[] comparables, Comparator<C> comparator);
final public void sort(C[] comparables)
{
sort(comparables, new Comparator<C>()
{
public int compare(C left, C right)
{
return left.compareTo(right);
}
});
}
final public void sort(C[] comparables, Comparator<C> comparator)
{
doSort(comparables, comparator);
}
}
And, here are the errors I'm getting:
java: name clash: sort(C[]) in AbstractSort and sort(java.lang.Comparable[]) in Sorter have the same erasure, yet neither overrides the other
Error:(25, 23) java: name clash: sort(C[],java.util.Comparator<C>) in AbstractSort and sort(java.lang.Comparable[],java.util.Comparator<java.lang.Comparable>) in Sorter have the same erasure, yet neither overrides the other
Thanks in advance for your help!
回答1:
Try writing implements Sorter<C>
. Without the type parameter, you use raw types, which disables certain aspects of generics for inherited methods. Specifically, with a raw super type, you only inherit erased method signatures. In your case, rather than inheriting the method sort(C[] comparables)
your inherit a method sort(Comparable[] comparables)
, which you can only override with an identical signature.
By specifying Sorter<C>
as the supertype, you inherit a method `sort(C[] comparables), which you can override with the identical signature.
Pitfalls such as this is why the Java Language Specification recommends that raw types should only be used for interfacing with non-generic legacy code, and requires compilers to emit a warning when raw types are used.
回答2:
I figured it out. Thanks for trying to help!
public interface Sorter<C extends Comparable<? super C>>
{
void sort(C[] comparables);
void sort(C[] comparables, Comparator<C> comparator);
}
public abstract class AbstractSort<C extends Comparable<? super C>> implements Sorter<C>
{
protected abstract void concreteSort(C[] comparables, Comparator<C> comparator);
final public void sort(C[] comparables)
{
sort(comparables, new Comparator<C>()
{
public int compare(Comparable left, Comparable right)
{
return left.compareTo(right);
}
});
}
final public void sort(C[] comparables, Comparator<C> comparator)
{
concreteSort(comparables, comparator);
}
}
回答3:
The problem is both class and interface has the void sort(C[])
, and they are conflicting. Try adding the @Override
notation to the class methods.
I would say you are over-engineering this problem. I would prefer the interface, then you can do
Sorter<SortableClass> sorter = new QuickSorter<SortableClass>();
It is simple, and it will get to the point.
来源:https://stackoverflow.com/questions/30651379/java-generics-error-have-the-same-erasure-yet-neither-overrides-the-other