我正在阅读Naftalin的《Java泛型和集合》一书.我想判断一下我对他们在第三章中提出的一点的理解.
他们解释了Comparable
接口如何允许我们控制我们可以相互比较的类型.在下面他们提供的代码示例中,他们说不可能比较Apple和Orange.确切地说,他们是这么说的:
由于苹果实现了
Comparable<Apple>
,很明显,你可以将苹果与苹果进行比较,但不能与橙子进行比较.
但正如您所看到的,在main
方法的最后一行,我们可以这样做,因为基类中的compareTo
最终被调用.所以我认为解决这个问题的方法是复制compareTo
方法的实现,将其移动到Apple和Orange类中的每一个?把它从基础Fruit类中移除?还是有更好的方法?
abstract class Fruit {
protected String name;
protected int size;
protected Fruit(String name, int size) {
this.name = checkNotNull(name);
this.size = size;
}
@Override
public boolean equals(Object o) {
if (o instanceof Fruit) {
Fruit that = (Fruit) o;
return this.name.equals(that.name) && this.size == that.size;
}
return false;
}
@Override
public int hashCode() {
return name.hashCode() * 29 + size;
}
protected int compareTo(@Nullable Fruit that) {
if (this.size > that.size) {
return 1;
} else if (this.size < that.size) {
return -1;
} else return 0;
}
}
}
class Apple extends Fruit implements Comparable<Apple> {
public Apple(int size) {
super("Apple", size);
}
@Override
public int compareTo(Apple apple) {
return super.compareTo(apple);
}
}
class Orange extends Fruit implements Comparable<Orange> {
protected Orange(int size) {
super("Orange", size);
}
@Override
public int compareTo(Orange orange) {
return super.compareTo(orange);
}
}
class TestFruit {
public static void main(String[] args) {
Apple apple1 = new Apple(1);
Apple apple2 = new Apple(2);
Orange orange1 = new Orange(1);
Orange orange2 = new Orange(2);
List<Apple> apples = List.of(apple1, apple2);
List<Orange> oranges = List.of(orange1, orange2);
// Both of these work as expected
System.out.println(Collections.max(apples)); // Apple{name=Apple, size=2}
System.out.println(Collections.max(oranges)); // Orange{name=Orange, size=2}
// But now, as expected, when you try to create a mixed list, it will no longer work
List<Fruit> mixed = List.of(apple1, orange2);
// Compile error on the below line
System.out.println(Collections.max(mixed));
// But this also works now, because compareTo from the Fruit class
// is being used here.
System.out.println(apple1.compareTo(orange1)); // -1
}
}