我有一个实现Comparable
接口的超类,并覆盖了compareTo()
方法。这个超类的一个子类必须实现它自己的compareTo()
方法,但由于名称冲突错误,我无法覆盖超类的compareTo()
方法。
public abstract class Superclass<T> implements Comparable<T> {
public int compareTo(T bo) { };
}
public class Subclass extends Superclass<Subclass> {
public <T> int compareTo(T bo) { }; // I get the name clash error here
}
为了解决这个问题,我试图使子类也是通用的(参见:Java Generics name clash, method not correctly overridden),但是我做错了或者这不起作用:
public abstract class Superclass<T> implements Comparable<T> {
public int compareTo(T bo) { };
}
public class Subclass<T> extends Namable<Subclass<?>> {
public int compareTo(T bo) { }; // I get the name clash error here
}
那么,如何覆盖超类的compareTo()
方法?
答案 0 :(得分:4)
此编译没有警告:
public abstract class Superclass<T> implements Comparable<T>{
@Override
public int compareTo(T o){
return 0;
};
}
public class Subclass extends Superclass<Subclass>{
@Override
public int compareTo(Subclass o){
return 0;
}
}
您的版本存在的问题是您使用的是其他T
。您使用的T
是方法定义的<T>
,而T
的原始SuperClass<T>
是SubClass
的替代。
答案 1 :(得分:4)
我认为你在这里有一个更普遍的设计问题。也就是说,为什么要在基类中实现compareTo
?在实践中,这几乎总会导致问题。
考虑
public class Subclass2 extends Superclass<Subclass2> {
...
}
Subclass sub = new Subclass();
Subclass2 sub2 = new Subclass2(); // the superclass portions of the two objects
// are identical
sub2.compareTo(sub); // what should be the result?
如果您有两个Superclass
实例(其超类部分相同,但子类部分可能不相同),您如何使用Superclass.compareTo
比较它们?如果不考虑具体的子类,则比较结果为0,不正确。如果您尝试直接比较不同子类的对象,则会因运行时异常而失败。如果在尝试直接比较对象之前尝试聪明并检查对象的运行时类型,则需要再次抛出某种运行时异常,而不是返回有效的结果。
我认为最好只在具体的子类中反转模式并实现compareTo
,其中编译器可以确保使用正确的参数类型调用该方法。如果您担心在子类之间复制代码,可以将其提升到超类中的protected final
方法。
代码示例:
public abstract class Superclass {
protected final int compareBasePortionTo(Superclass other) { ... };
}
public class Subclass extends Superclass implements Comparable<Subclass> {
public int compareTo(Subclass other) {
int baseCmp = compareBasePortionTo(other);
if (baseCmp != 0)
return baseCmp;
// compare subclass properties
};
}