我正在閱讀 Naftalin 的“Java 泛型和集合”一書。我想檢查一下我對他們在第 3 章中提出的觀點的理解。
他們解釋了Comparable界面如何讓我們控制我們可以相互比較的型別。在他們提供的以下代碼示例中,他們說無法將Apple與Orange進行比較。準確地說,這就是他們所說的:
由于 Apple 實作
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
}
}
uj5u.com熱心網友回復:
- 一個類有方法
compareTo(Fruit)并不意味著它實作了Comparable<Fruit>。只有相反才是正確的。 - 在java API中,需要比較的方法是基于
Comparable介面的,而不是檢查類是否有compareTo方法。
既然Fruit不實作Comparable<Fruit>(實作了就是設計問題),書上說的都是對的。你可以看到Collections.max不能用List<Fruit>.
IMO,讓我們感到困惑的compareTo是Fruit.
Comparable這個名字對方法來說是模棱兩可的,
所以按照慣例,我們應該compareTo只在實作時才命名一個方法Comparable。- 由于靜態系結,可能會呼叫錯誤的方法
// Apple#compareTo is called System.out.println(apple1.compareTo(apple2)); Fruit fruitWhichIsApple2 = apple2; // Fruit#compareTo is called System.out.println(apple1.compareTo(fruitWhichIsApple2));
盡管它被標記為protected(避免從其他包類中使用),但如果我們將其重命名為其他名稱,則非常清楚。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/460175.html
