Hallo zusammen,
Ich will mein Problem anhand eines Beispiels erläutern:
Ich habe 3 Arraylists mit verschiedensten Objekten. Die erste enthält Bücher, die zweite Autos und die dritte enthält die Kontakte aus meinem Adressbuch.
Ich will über 3 Knöpfe die zugehörige ArrayList in einer JList sortiert angezeigt haben. Alle 3 Klassen sind vergleichbar untereinander.
Ich habe bereits eine JList mit eigenem Model erstellt, die Objekte einer Klasse aufnehmen und sortieren kann.
...
public void sort(){
Collections.sort(content);
fireContentsChanged(this, 0, content.size());
}
Das Problem ist nun, dass ich in dieser Liste nur Bücher abspeichern kann. Wenn ich also Autos angezeigt haben möchte, brauche ich eine andere Liste die angezeigt wird, da die Superklasse Object keine Vergleiche erlaubt.
Gibt es eine Möglichkeit, alle 3 Listen in der JList anzeigen zu können (nicht gleichzeitig, immer nur eine mit Objekten der gleichen Klasse), ohne auf ein eigenes Model zu verzichten und ohne 3 JLists zu erstellen?
Wenn alle Klassen Comparable implementieren, hast du damit doch dein Interface schon gefunden. Statt List einfach List<Comparable<?>> (oder ggf List<? extends Comparable<?>>).
Erstmal danke für die Hilfe, mit Interfaces kenne ich mich noch nicht so gut aus. Aber es funktioniert trotzdem noch nicht so wie ich will.
Wenn ich zur Initialisierung im Konstruktor
public Konstruktor (ArrayList<Comparable> eineListe){
...
}
stehen habe, dann motzt er an der Stelle
private eineMethode(){
new Konstruktor(new ArrayList<Auto>());
}
rum, weil er ArrayList möchte. An einer Stelle erzeuge ich ja die spezifische ArrayList mit den Autos, und dort will ich nicht auf ArrayList gehen, weil mir das viele umständliche Casts beschert.
Danke für eure Tipps, ich glaube ich habe jetzt einigermaßen verstanden wie Interfaces funktionieren.
Der Tipp von @Natac hat mich viele ArrayLists in meinem Code erstellen lassen. Da habe ich gemerkt, dass viele Methoden viel zu spezifisch sind (um beim Beispiel zu bleiben: Ich verwende z.Z. nur die Klasse Buch, die anderen Klassen kommen erst später nach).
Da ich einige Dinge allgemeiner schreiben muss lohnt es sich sogar, eine Superklasse für die alternativen Klassen in den ArrayLists zu schreiben. Das sollte mein Problem beheben und der Compiler akzeptiert alles
@bERt0r : das „extends“ funktioniert nur, falls ich ein eigenes Interface erstelle (was du vermutlich weißt). Da alle Comparable verwenden brauche ich sowas ja aber nicht. Allerdings sagt der Compiler, dass ich ArrayList nicht dort einsetzen darf, wo ArrayList gefordert ist.
Und wie vergleichst du da Autos mit Büchern? Kann doch so nicht gehen - oder ist schlechtes Design (da würde ja in der Auto-Klasse Code sein, der was von Büchern weiß)
Okay da habe ich mich wohl missverständlich ausgedrückt:
Es wird nur gleiches mit gleichem verglichen. Die Klasse Bücher hat eine andere compareTo-methode als Autos. Und in der JList soll immer nur die Liste mit EINER Klasse (also entweder nur Bücher oder nur Autos etc.) angezeigt werden. Im Endeffekt geht es darum, eine (modifizierte) JList zu besitzen. Der Nutzer kann dann entscheiden, welche der ArrayLists (Bücher, Autos,…) er in dieser JList angezeigt haben möchte.
Ich hoffe es ist jetzt etwas klarer worauf ich hinaus möchte.
Drei ListModels wäre halt CopyPaste und immer den Klassennamen in ArrayList<?> geändert. Da dachte ich das geht doch sicher auch einfacher. Abgesehen davon muss ich ja dann abfragen starten welches ListModel ich wähle.
Ich bin gerade an der Superklasse dran, ich melde mich nochmal sobald sich da was tut.
[QUOTE=TheAceOfSpades]Drei ListModels wäre halt CopyPaste und immer den Klassennamen in ArrayList<?> geändert. Da dachte ich das geht doch sicher auch einfacher. Abgesehen davon muss ich ja dann abfragen starten welches ListModel ich wähle.
Ich bin gerade an der Superklasse dran, ich melde mich nochmal sobald sich da was tut.[/QUOTE]
Deswegen hatte ich das ja um 8:20 Uhr vorgeschlagen, eine Überklasse oder ein Interface zu erstellen, von dem die 3 Klassen erben
Naja, etwas einfacher könntest du es haben, wenn du nicht so „stark“ auf Generics setzt:
private List<T> liste = new ArrayList<T>();
}```
und erstellen würdest du das Model dann halt so: `new MyListModel<Auto>();`. Wenn du aber wirklich unterschiedliche Lists in deinem Model unterstützen möchtest, dann musst du erstmal die Feinheiten von Generics verstehen. Also so Sachen wie `<? extends ...>` oder `<? super ...>`. Ich hab grad etwas bedenken obs hilfreich ist oder nicht, aber vllt kannst du ja mal versuchen das hier Nachzuvollziehen:
```import java.util.ArrayList;
import java.util.List;
interface Alpha {}
interface Beta extends Alpha {}
public class Gamma implements Beta {
public void beispiel(List<Beta> liste) {
liste.add(this); // geht
}
public void beispielExtends(List<? extends Beta> liste) {
liste.add(this); // geht nicht (readonly)
}
public void beispielSuper(List<? super Beta> liste) {
liste.add(this); // geht
}
public void use() {
List<Alpha> alpha = new ArrayList<Alpha>();
List<Beta> beta = new ArrayList<Beta>();
List<Gamma> gamma = new ArrayList<Gamma>();
alpha.add(this); // geht
beta.add(this); // geht
gamma.add(this); // geht
beispiel(alpha); // geht
beispiel(beta); // geht
beispiel(gamma); // geht nicht
beispielExtends(alpha); // geht nicht
beispielExtends(beta); // geht
beispielExtends(gamma); // geht
beispielSuper(alpha); // geht
beispielSuper(beta); // geht
beispielSuper(gamma); // geht nicht
}
}```
Das mit den Interfaces ist glaube ich gerade noch ein bischen viel für mich, aber danke fürs aufzeigen. Ich versuche es mal im Hinterkopf zu behalten für das was kommt…mir spukt da schon was im Kopf rum wie ich es doch gebrauchen könnte.
Mein Problem habe ich aber ganz schlicht durch Erstellen einer Superklasse “Alternative” gelöst. In dem Kontext in dem ich das Ganze benötige hätte ich früher oder später sowieso darauf zugreifen müssen.
Die Lösung, falls das mit der Superklasse nicht funktioniert hätte, wäre, wie @Tomate_Salat es vorgeschlagen hat, das mit <? extends ...> gewesen. Leider muss ich mich darin noch etwas einlesen und zum Glück brauche ich es gerade nicht :P.