Zastanawiam się, czy jest tam kiedykolwiek ważny przypadek zastosowania w następujących przypadkach:Czy porównywalne kiedykolwiek porównać do innego typu?
class Base {}
class A implements Comparable<Base> {
//...
}
Wydaje się, że wspólny wzór (patrz Collections dla wielu przykładów), aby przyjąć zbiór typu T
, gdzie T extends Comparable<? super T>
.
Ale wydaje się technicznie niemożliwe, aby wypełnić kontrakt z compareTo()
w porównaniu do klasy bazowej, ponieważ nie ma sposobu, aby zapewnić, że inna klasa nie rozszerza bazy o sprzeczne porównanie. Rozważmy następujący przykład:
class Base {
final int foo;
Base(int foo) {
this.foo = foo;
}
}
class A extends Base implements Comparable<Base> {
A(int foo) {
super(foo);
}
public int compareTo(Base that) {
return Integer.compare(this.foo, that.foo); // sort by foo ascending
}
}
class B extends Base implements Comparable<Base> {
B(int foo) {
super(foo);
}
public int compareTo(Base that) {
return -Integer.compare(this.foo, that.foo); // sort by foo descending
}
}
Mamy dwa zajęcia rozciągające Base
używając porównań, które nie podążają wspólną regułę (jeśli nie było powszechną regułą, to prawie na pewno będzie realizowany w Base
). Jeszcze następujące złamany porządek zostanie skompilowany:
Collections.sort(Arrays.asList(new A(0), new B(1)));
nie byłoby bezpieczniej tylko zaakceptować T extends Comparable<T>
? Czy jest jakiś przypadek użycia, który sprawdzi wildcard?
Moje jelito mówi "nie" (jabłka i pomarańcze), ale jedynym powodem, dla którego "mógłbyś" to rozważyć, jest to, że NIGDY nie chcesz porównywać klas dzieci w inny sposób, niż wtedy, gdy robisz klasę rodzicielską. Oczywiście zawsze możesz po prostu nazwać "super.compareTo" zamiast: – MadProgrammer
Myślę, że możesz nieco wyjaśnić swój tytuł. Wydaje mi się, że bardziej interesujące pytanie pojawia się w twoim poście: "Dlaczego metody w kolekcjach zadeklarowane do pracy na" T przedłuża porównywalną super T> "zamiast" T przedłuża porównywalną "?" Oczywiście nie jest to świetny tytuł, ale myślę, że tytułowo zorientowany w taki sposób mógłby być lepszy. –
Others
Wiem, że Java 'enum' s użyć ich klasy bazowej do 'porównywalne'. Cała Java 'enum's wywodzi się z klasy bazowej' java.lang.Enum', która implementuje 'Porównywalne', gdzie 'E' jest klasą potomną (to jest wyliczenie, którego używasz). –
markspace