java - 在 Java 中对子类进行排序

标签 java sorting inheritance

假设一个 Superclass implements Comparable<Superclass> , 这样 Arrays.sort(ArrayOfSuperInstances);使用这个 compareTo(Superclass other)方法进行排序。这是否保证 Subclass extends Superclass 的实例数组?将使用 Arrays.sort(ArrayOfSubInstances); 以相同的方式排序? (假设子类定义中没有重载compareTo)

或者换句话说,将Subclass默认继承 compareTo其方法Superclass , 这样就可以盲目使用 Arrays.sort()知道它们将被排序为父类(super class)?

最佳答案

是的——这就是多态背后的全部原则,特别是 Liskov substitution principle .基本上,如果 A 是 B 的子类,那么您应该能够在任何可以使用 B 的地方使用 A,并且它的行为本质上应该与 B 的任何其他实例(或 B 的其他子类)相同。

因此,它不仅会发生,而且几乎总是您希望发生的事情。 compareTo 通常是错误的在子类中。

为什么?嗯,一部分Comparable<T>契约是比较是传递的。因为你的父类(super class)可能不知道它的子类在做什么,如果一个子类覆盖了 compareTo以这种方式给出不同于其父类(super class)的答案,它违反了契约。

例如,假设您有 Square 和 ColorSquare 之类的东西。四方的compareTo比较两个正方形的大小:

@Override
public int compareTo(Square other) {
    return this.len - other.len;
}

...而 ColorSquare 还添加了颜色比较(假设颜色是可比较的)。 Java 不会让您拥有 ColorSquare 工具 Comparable<ColorSquare> (因为它的父类(super class)已经实现了 Comparable<Square> ),但是你可以使用反射来解决这个问题:

@Override
public int compareTo(Square other) {
    int cmp = super.compareTo(other);
    // don't do this!
    if (cmp == 0 && (other instanceof ColorSquare)) {
        ColorSquare otherColor = (ColorSquare) other;
        cmp = color.compareTo(otherColor.color);
    }
    return cmp;
}

乍一看这看起来很无辜。如果两个形状都是 ColorSquare,它们将比较长度和颜色;否则,他们只会比较长度。

但是如果你有:

Square a = ...
ColorSquare b = ...
ColorSquare c = ...

assert a.compareTo(b) == 0;  // assume this and the other asserts succeed
assert a.compareTo(c) == 0;
// transitivity implies that b.compareTo(c) is also 0, but maybe
// they have the same lengths but different color!
assert b.compareTo(c) == 1; // contract is broken!

关于java - 在 Java 中对子类进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11928656/

相关文章:

java - 来 self 的自定义 servlet 的 Kerberos 身份验证?

java - ClassNotFoundException : org. ear 文件中的 jaxen.JaxenException

java - java 按升序对矩阵的列进行排序

java - 对通用接口(interface)列表进行排序

inheritance - Symfony2、Doctrine2 的继承问题

java - 文件构造函数说明

java - Java 中的 pretty-print JSON

mysql - 显示按 "on the fly score calculation"排序的带分页的文章的最佳做法是什么

java - 阻止要扩展的接口(interface)

javascript - 主干 View 属性 : one on instance, 是原型(prototype)上的一个吗?