ich habe mir eine generische Klasse MyTreeNode<T>, die einen Baumknoten repräsentiert, definiert und habe nun verschiedene von dieser abgeleitete Klassen erstellt, also zum Beispiel MyStringTreeNode extends MyTreeNode<String>, die der jewiligen Basisklasse noch Funktionalität hinzufügen. Erzeuge ich nun ein Objekt der Klasse MyStringTreeNode und verwende die von MyTreeNode<String> geerbte Methode getChildren, so erhalte ich Objekte vom Typ MyTreeNode<String> zurück. Diese möchte ich nun gerne einfach nach MyStringTreeNode casten. Dies funktioniert aber offensichtlich nicht und bringt zur Laufzeit eine java.lang.ClassCastException.
Meine Fragen daher:
1. Warum tritt das Problem auf?
2. Ich würde gerne die von MyTreeNode<String> bereit gestellten Methoden nutzen und eben noch zusätzliche Methoden verwenden. Wie kann ich das erreichen?
Wenn die einzelnen Objekte wirklich vom Typ MyStringTreeNode SIND, dann kann man sich auch casten. (Der Computer irrt sich da im Allgemeinen eher selten). Ein KSKB würde vielleicht helfen.
danke für die schnellen Antworten. Leider ist mein Problem noch nicht gelöst
@Noctarius: Freilich habe ich die Klasse so definiert ...
@Marco13: ein KSKB habe ich mir ebenfalls erstellt und das funktioniert ebenfalls nicht. Es sieht folgendermaßen aus:
andersrum würde es funktionieren:
ArrayList<String> l = new MyArrayList();
List<String> l2 = new MyArrayList();
mit Generics hat das im Grunde gar nix zu tun, hättest du auch zunächst ohne testen können
Java:
publicclassTest{publicstaticvoidmain(String[] args){Object o =newObject();MyArrayList myList =(MyArrayList)o;// macht wenig Sinn, nicht jedes beliebige Object kann sich wie MyArrayList verhalten,// funktioniert aber, falls in o zufällig ein MyArrayList-Objekt drinsteckt}}classMyArrayListextendsObject// extends kann man auch weglassen, alles erbt von Object{}
Um das blöde Casten zu vermeiden, gibt es einen generischen Trick:
Java:
importjava.util.List;publicabstractclassMyTreeNode<T,NextendsMyTreeNode<T,N>>{abstractList<N>getChildren();//N ist "die Klasse, wo wir grade drin sind"}importjava.util.List;importjava.util.ArrayList;publicclassMyStringTreeNodeextendsMyTreeNode<String,MyStringTreeNode>{List<MyStringTreeNode> children =newArrayList<MyStringTreeNode>();publicList<MyStringTreeNode>getChildren(){return children;}}
oder mit den children in der Papaklasse:
Java:
importjava.util.List;importjava.util.ArrayList;publicabstractclassMyTreeNode<T,NextendsMyTreeNode<T,N>>{privateList<N> children =newArrayList<N>();publicList<N>getChildren(){return children;}}publicclassMyStringTreeNodeextendsMyTreeNode<String,MyStringTreeNode>{}