# Was macht `public class ClassName<T extends Comparable<T>>`?



## csjacq (21. Jan 2018)

Hallo,

ich bin zwar etwas mit generics vertraut, aber ich weiß nicht genau was solch eine Klassendekleration machen soll:


```
public class ClassName<T extends Comparable<T>>{
...
}
```


`Comparable<T>` ist ja ein Interface. Und in dieser befindet sich nur die Methode `compareTo`.
Was macht eine solche Klasssendekleration und wie nutze ich diese?


----------



## Javinner (21. Jan 2018)

@csjacq 
Willst du jetzt wissen, wie man das Interface Comparble<T> benutzt, oder?
Die Klasse ClassName kann ja a) Roh und b) etwas erhalten, was von Comparable<T> abgeleitet wurde.
Bitte um präzise Angabe


----------



## mrBrown (21. Jan 2018)

Das gibt an, dass die Klasse ClassName einen generischen Parameter vom Typ Comparable hat, man kann es dann zB als ClassName<Integer> deklarieren.


----------



## csjacq (21. Jan 2018)

Javinner hat gesagt.:


> @csjacq
> Bitte um präzise Angabe


Zuerst will ich will ich die Syntax und die damit verbundene Semantik verstehen.  Also warum man  <T extends Comparable<T>> so schreibt... Wird damit `Comparable<T>` auf die Klasse `ClassName` abgeleitet? Warum schreibt man nicht einfach: `public class ClassName<T> extends Comparable<T>` bzw. was ist der unterschied? Und was bringt uns das jetzt...?

In `ClassName` würde ich jetzt etwas implementieren, also es ist nicht roh... Das Interface `Comparable<T>` hat doch nur eine einzige Methode `compareTo`, oder? Wie kann ich diese nutzen / auf diese zugreifen?


----------



## Meniskusschaden (21. Jan 2018)

csjacq hat gesagt.:


> Warum schreibt man nicht einfach: `public class ClassName<T> extends Comparable<T>`


Weil `ClassName` dann ein Subtyp von `Comparable` sein müsste. Es soll aber `T` ein Subtyp von `Comparable` sein.


----------



## Javinner (21. Jan 2018)

@csjacq
Das Thema ist recht umfangreich, ein Teil, in dem es um compareTo() Methode geht, erläutere ich kurz.
Beispiel Klasse String, implementiert das Interface Comparable<String> und die Methode compareTo() vergleicht ein String mit dem anderen auf Gleichheit. Dabei liefert die Methode:

1, wenn der String größer, als der zweite String ist
-1, wenn der String kleiner, als der zweite String ist
0, wenn beide Strings gleich sind.
Dabei ist String aaa kleiner, als String abb.

So ist es möglich, für eigene Klassen das Interface Comparable zu implementieren, um die Exemplare der Klassen miteinander vergleichen zu können. Jedoch muss die Grundlage dafür geschaffen werden.


Spoiler: Klasse Produkt implements Comparable<Produkt>





```
class Produkt implements Comparable<Produkt>
{

    private final String name;
    private final String werkstoff;
    private final int id;

    public Produkt(String name, String werkstoff, int id)
    {
        this.name = name;
        this.werkstoff = werkstoff;
        this.id = id;
    }

    @Override
    public int compareTo(Produkt t)
    {
        if (this.hashCode() > t.hashCode()) {
            return 1;
        } else if (this.hashCode() < t.hashCode()) {
            return -1;
        } else {
            return 0;
        }
    }

    @Override
    public int hashCode()
    {
        int hash = 3;
        hash = 37 * hash + Objects.hashCode(this.name);
        hash = 37 * hash + Objects.hashCode(this.werkstoff);
        hash = 37 * hash + this.id;
        return hash;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Produkt other = (Produkt) obj;
        if (this.id != other.id) {
            return false;
        }
        if (!Objects.equals(this.name, other.name)) {
            return false;
        }
        return Objects.equals(this.werkstoff, other.werkstoff);
    }

}
/** Main */
Produkt radA = new Produkt("Rad", "Holz", 1234);
Produkt radB = new Produkt("Rad", "Holz", 1234);
Produkt radC = new Produkt("Rad", "Stahl", 2345);

System.out.println(radA.compareTo(radB)); //0
System.out.println(radA.compareTo(radC)); //1
```



Durch das Überschreiben der Methoden equals und hashCode bekommt jedes Exemplar der Klasse Produkt
eine eigene Identität, so dass die Basis für ein Vergleich geschaffen wurde, vereinfacht ausgedrückt.

Zum Thema HashCode gibt es hier ein richtig guten Artikel.
Sonst kann ich dir zum Thema nur passende Literatur empfehlen, Java ist auch eine Insel wäre da meine erste Wahl.


----------



## csjacq (21. Jan 2018)

Hier wird aber das Interface Comparable nicht implementiert, sondern abgeleitet und ich kann nicht @Override. Was bringt mir also so eine Klassendekleration?


----------



## Javinner (21. Jan 2018)

Hier wird der Klasse ein Typ zugewiesen, welcher von Comparable<T> abgeleitet wurde, und dieser kann String oder auch Integer sein, als Beispiel genommen


----------



## Meniskusschaden (21. Jan 2018)

csjacq hat gesagt.:


> Was bringt mir also so eine Klassendekleration?


Sie stellt sicher, dass bei der Benutzung der Klasse `ClassName` für die Typvariable T nicht beliebige Typen benutzt werden können, sondern nur solche, die `Comparable` implementieren. In der Implementierung von `ClassName` soll also vermutlich irgendwo `compareTo` auf einem T-Objekt aufgerufen werden.


----------



## csjacq (21. Jan 2018)

Meniskusschaden hat gesagt.:


> Sie stellt sicher, dass bei der Benutzung der Klasse `ClassName` für die Typvariable T nicht beliebige Typen benutzt werden können, sondern nur solche, die `Comparable` implementieren. In der Implementierung von `ClassName` soll also vermutlich irgendwo `compareTo` auf einem T-Objekt aufgerufen werden.


Gibt es in Java Typen, die schon Comparable implementieren? Wenn ja welche wären das? Sonst muss ich eine extra Klasse erstellen, die Comparable implementiert und @Override durchführt, oder?


----------



## Meniskusschaden (21. Jan 2018)

csjacq hat gesagt.:


> Gibt es in Java Typen, die schon Comparable implementieren?


Ja, @mrBrown und @Javinner haben oben ja schon welche genannt. Ansonsten stehen hier noch weitere.


----------



## mrBrown (21. Jan 2018)

Javinner hat gesagt.:


> Dabei liefert die Methode:
> 
> 1, wenn der String größer, als der zweite String ist
> -1, wenn der String kleiner, als der zweite String ist
> 0, wenn beide Strings gleich sind.


Im allgemein sind das übrigens kleiner 0, gleich 0 und größer 0, das ist nicht auf  +/-1 beschränkt


----------



## Javinner (22. Jan 2018)

@mrBrown
Wo kann ich es nachlesen?


----------



## Flown (22. Jan 2018)

@Javinner In der JavaDoc HIER.


----------



## Javinner (22. Jan 2018)

Flown hat gesagt.:


> @Javinner In der JavaDoc HIER.


Vielen Dank. Habe die Implementierung der Methode compareTo() schon in einigen Klassen gesehen und nahm an, dass es so sein muss.


----------

