Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
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:
Ich habe mir eine Klasse MyArrayList definiert:
Java:
import java.util.ArrayList;
public class MyArrayList extends ArrayList<String> {
private static final long serialVersionUID = -5164702379587769464L;
}
und dann folgenden Cast probiert (der mit einem Laufzeitfehler scheiterte):
Java:
import java.util.ArrayList;
import java.util.HashMap;
public class MyGenericsTest {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
MyArrayList myList = (MyArrayList) list;
}}
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:
public class Test {
public static void main(String[] args) {
Object o = new Object();
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
}
}
class MyArrayList extends Object
// extends kann man auch weglassen, alles erbt von Object
{}
Um das blöde Casten zu vermeiden, gibt es einen generischen Trick:
Java:
import java.util.List;
public abstract class MyTreeNode<T, N extends MyTreeNode<T, N>> {
abstract List<N> getChildren(); //N ist "die Klasse, wo wir grade drin sind"
}
import java.util.List;
import java.util.ArrayList;
public class MyStringTreeNode extends MyTreeNode<String, MyStringTreeNode> {
List<MyStringTreeNode> children = new ArrayList<MyStringTreeNode>();
public List<MyStringTreeNode> getChildren() {
return children;
}
}
oder mit den children in der Papaklasse:
Java:
import java.util.List;
import java.util.ArrayList;
public abstract class MyTreeNode<T, N extends MyTreeNode<T, N>> {
private List<N> children = new ArrayList<N>();
public List<N> getChildren(){
return children;
}
}
public class MyStringTreeNode extends MyTreeNode<String, MyStringTreeNode> {
}