Comparable und Generics

Hi,

ich spiele gerade mit Java Generics rum und hab beim Spielen ein kleines Verständnisproblem.

Ich hab zwei voneinander abgeleitete Klassen C1 und C2. Die Oberklasse implementiert ein Interface, zum Beispiel Comparable<T>. In C1 und C2 muss die CompareTo() Methode unterschiedlich sein.
In einer dritten Klasse hab ich ein Methode die sich auf das CompareTo() von C1 oder C2 abstützt.

Irgendwie bin ich zu blöd das mit Generics richtig hinzubekommen, hier mal mein Code:
[Java]
class FindMax<T extends Comparable<? super T>>
{
public T findMax(T o1, T o2)
{
T max = o1;

if (o1.compareTo(o2) < 0)
{
max = o2;
}
return max;
}
}

class C1 implements Comparable<C1>
{
private int mSize;

public C1 (int aSize)
{
mSize = aSize;
}

public int compareTo(C1 o)
{
System.out.println("CompareTo::C1");
return (mSize - o.mSize);
}

public String toString()
{
return "C1 " + mSize;
}
}

class C2 extends C1
{
private int mValue;

public C2(int aSize, int aValue)
{
super(aSize);
mValue = aValue;
}

public int compareTo(C2 o)
{
System.out.println("CompareTo::C2");
return (mValue - o.mValue);
}

public String toString()
{
return "C2 " + mValue;
}
}


public class TestFindMaxNeu
{
public static void main(String[] args)
{
FindMax<C1> maxi1 = new FindMax<C1>();
C1 c1 = new C1(320);
C1 c2 = new C1(545);

C1 max1 = maxi1.findMax(c1, c2);
System.out.println(max1);
System.out.println("");

FindMax<C2> maxi2 = new FindMax<C2>();
C2 eb1 = new C2(320, 15);
C2 eb2 = new C2(545, 9);

C2 max2 = maxi2.findMax(eb1, eb2);
System.out.println(max2);

System.out.println(eb1.compareTo(eb2));
System.out.println("");

}
}
[/Java]

Der Code kompiliert nur wird beides Mal bei FindMax die compareTo()-Methode in C1 aufgerufen.

Wie muss ich denn den Code ändern damit bei der zweiten Instanz maxi2 auch die compareTo-Methode von C2 aufgerufen wird.

Danke schon mal
Patrick

PS: Anstelle von FindMax könnte auch was ganz kompliziertes stehen. Die Funktion hab ich nur gewählt, weil sie so einfach ist.
 
compareTo(C1) und compareTo(C2) sind zwei unterschiedliche Methoden. Du musst (leider) auch in deiner zweiten Klasse compareTo(C1) schreiben um die Originalmethode zu überschreiben, dann must Du einen Cast von C1 auf C2 ausführen. Damit geht die Typsicherheit über Bord.

Persönlich ziehe ich es vor, in dieser Situation zweimal das Interface Comparator (je einmal für C1 und für C2) zu implementieren. Das ist dann weiterhin typsicher.
 
C2 hat die Funktionen [c]compareTo(C1 o)[/c] und [c]compareTo(C2 o)[/c] und erbt von C1 das Interface [c]Comparable<C1>[/c].

Meine Vermutung ist, dass C2 das Interface [c]Comparable<C2>[/c] bräuchte. Das kannst du allerdings nicht implementieren, weil das Interface bereits mit einer anderen Klasse implementiert ist.
 
die methodensignatur ist ganz einfach anders. arbeite bei vererbung immer mit @Override. wenn du das in beiden klassen bei der compareTo machst, siehst du auch gleich, dass da was nicht stimmt 🙂
 
Zuletzt bearbeitet:
Hallo,

erst mal vielen Dank für die Antworten.
Ich muss jetzt nur noch verstehen, warum beim Aufruf über maxi2.findMax(eb1,eb2) die "falsche" compareTo-Methode aufgerufen wird und beim direkten Aufruf eb1.compareTo(eb2) die richtige ...

Ich hab gedacht, dass bei maxi2 das T durch das C2 "ersetzt" wird, also eine Instanz entsteht bei der alle T durch ein C2 ersetzt werden. Irgendwo ist da wohl noch ein Knoten in meinem Hirn ???:L

Gute Nacht
Pat
 
generics bieten lediglich eine typsicherheit vor der Laufzeit. intern wird jede List<xy> einfach nur als list interpretiert
 
Wie muss ich denn den Code ändern damit bei der zweiten Instanz maxi2 auch die compareTo-Methode von C2 aufgerufen wird.

compareTo(C1 c1) hinzufügen. Je nachdem, ob zur Laufzeit ein Objekt Typs C2 vorliegt und die Methode mit einem Objekt C1 oder C2 aufgerufen wird, wird dann die entsprechende compareTo()-Methode aus C2 aufgerufen. Es wird die Methode mit der passendsten Signatur gewählt in diesem Fall und der jeweilige Typ der Objekte zur Laufzeit ist entscheidend.
 

Zurück
Oben