Java 参数类型必须为超类时compareTo()的最佳实践

Java 参数类型必须为超类时compareTo()的最佳实践,java,comparable,Java,Comparable,我正在寻找在类实现Comparable的情况下定义compareTo()方法的最佳实践。因此,方法的签名必须是 public int compareTo(BaseClass arg) 首先要做的一件显而易见的事情是检查arg是否是此类的实例,如果是,则转换为类,并比较成员。但是,如果参数不是这个类的,而是其他一些也实现了基类的类,那么我应该返回什么以使其自反呢 我知道,最好的做法是只为类定义compareTo(),但是水已经过了坝。你的错误在于你的问题。 您不必实现public int com

我正在寻找在类实现Comparable的情况下定义compareTo()方法的最佳实践。因此,方法的签名必须是

public int compareTo(BaseClass arg)
首先要做的一件显而易见的事情是检查arg是否是此类的实例,如果是,则转换为类,并比较成员。但是,如果参数不是这个类的,而是其他一些也实现了基类的类,那么我应该返回什么以使其自反呢


我知道,最好的做法是只为类定义compareTo(),但是水已经过了坝。

你的错误在于你的问题。 您不必实现
public int compareTo(BaseClass arg)
。您必须实现“public int compareTo(YourClass arg)”

在这种情况下,您不必使用
instanceof
并执行强制转换。这就是引入泛型的原因:为了避免铸造

但如果您仍然希望使用基类作为参数,请至少执行以下操作:

public class Test {

}

class SubTest <T extends Test> implements Comparable<T> {
    @Override
    public int compareTo(T o) {
        // add your code with instanceof here
        return 0;
    }
}
公共类测试{
}
类子测试实现了可比较的{
@凌驾
公共内部比较(TO){
//在此处添加带有instanceof的代码
返回0;
}
}

至少这种方法要求参数是基类的子类。

引用有效Java,第12项:

让我们看一下合同的条款。第一 条款规定,如果你颠倒了比较的方向 在两个对象引用之间,会发生预期的事情:如果 第一个对象小于第二个对象,那么第二个对象必须大于第二个对象 比第一个好;如果第一个对象等于第二个对象,则 第二个必须等于第一个;如果第一个物体更大 大于第二个,则第二个必须小于第一个。这个 第二条规定,如果一个物体大于一秒, 第二个大于第三个,那么第一个必须是 大于第三个。最后一条规定,所有 当与任何值进行比较时,compare as equal必须产生相同的结果 其他对象

这三条规定的一个后果是平等测试 由比较法施加的限制必须遵守施加的相同限制 由相等约束:自反性、对称性和及物性。 因此,同样的警告也适用:无法扩展 具有新值组件的可实例化类,同时保留 与合同相比,除非你愿意放弃 面向对象抽象(第8项)。同样的解决方法也适用, 也如果要将值组件添加到实现 可比较,不要扩展它;编写一个包含 第一个类的实例。然后提供一个“视图”方法 返回此实例。这使您可以实现任何比较 方法,同时允许其客户端 将第二个类的实例视为第一个类的实例 需要的时候


您应该按照@BalusC在他的评论中建议的做——对所有子类使用基类的compareTo()方法,或者通过创建一个包含第一个类实例的不相关类来执行上面建议的解决方法。

在本文中,自反意味着
obj.compareTo(obj)==0
。你这里的反身是什么意思

就compareTo(to)的指定约定而言,如果所涉及的类无法进行有意义的比较,那么所需的语义就是抛出ClassCastException

e、 g.给定

class Fruit {/* ..*/ }

class Apple extends Fruit {/* .. */ }

@Ignore("bad OO")
class GrannySmithApple extends Apple {/* .. */ }

class Orange extends Fruit {/* ... */ }
可以说

   Fruit a = new Apple();
   Fruit b = new GrannyApple();
   Fruit c = new Orange();

   // compare apples with apple?
   // makes sense to expect an int value
   r = a.compareTo(b)

   // compare apples with oranges?
   // makes sense to expect an exception
   boolean excepted = false;
   try {
       c.compareTo(a);
   } catch (ClassCastException e) { 
      excepted = true;
   } finally {
      assert excepted : "How can we compare apples with oranges?"
   }

假设它是一个抽象类或接口,为什么不让
BaseClass
实现或扩展
Comparable
并利用实现细节来实现类的实现者呢?你是在建议基类实现compareTo(基类),然后让子类覆盖它吗?我的意思是a.compareTo(b)==-b.compareTo(a),如果a.compareTo(b)>0,b.compareTo(c)>0,那么a.compareTo(c)>0这就是整个自反、传递和对称属性。如果两个子类没有意义上的可比性,则上述情况不必成立(如果您确实抛出了所需的异常)。我就是这样读你的问题的(如果不是这样的话,你应该澄清一下)。我改变了基类:类测试实现了Comparable,它看起来更快乐。谢谢