Java名称冲突错误

时间:2011-03-04 11:23:48

标签: java generics

我有一个实现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()方法?

2 个答案:

答案 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
  };
}