Rain Geschrieben 12. Januar 2008 Teilen Geschrieben 12. Januar 2008 Hallo an alle, Ich habe ein Verständnis-Problem: folgende Vererbungshierarchie ist gegeben: class A { private int a; public A(int a) { setA(a); } void doSomething(){ System.out.println("do Something - class B"); } } class B extends A { public B(int a) { super(a); } void doSomething(){ System.out.println("do Something - class B"); } } Nun lege ich eine Arraylist an: ArrayList<A> foo = new ArrayList<A>; foo.add(new A(1)); foo.add(new B(2)); Und nun möchte ich aus der ArrayList auslesen: public A getMe(int num){ return (A) (foo.get(num)); } Mein Problem das ich damit habe, ist dass die Vererbungshierarchie mir hier irgendwie verloren geht. Wenn ich jetzt die getMe Methode verwende, dann kann ich immer nur das doSomething() von Klasse A aufrufen, nicht aber das von Klasse B auch wenn das Objekt von der Klasse B ist... Meine Frage ist nun, wie löst man das elegant? Gibt es einen Weg, um eine Funktion zu schreiben, die mir je nach dem von welcher Klasse das Objekt ist, den richtigen Typ zurückgibt? Prinzipiell kann ja in Java der Rückgabewert einer Funktion nur von einem Typ sein, oder? also wenn z.B das Element in der ArrayList vom Typ ( dann gibt er mit ein Objekt vom Typ B zurück und nicht von der Superklasse A... Ich hoffe ich habe das einigermaßen verständlich erklärt... Vielen Dank für eure Hilfe im Voraus Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Abd Sabour Geschrieben 17. Januar 2008 Teilen Geschrieben 17. Januar 2008 Hallo, alsooo gleich mal ran ans Werk ;-). 1. Warums steht in deiner doSomething-Methode von Klasse A "do Something - class B" ? Müsste da nicht eigentlich "do Something - class A" stehen, damit du unterscheiden kannst, wessen doSomething du gerade aufrufst ? 2. Wenn du ein Objekt der Klasse B hast und in Klasse B die doSomething-Methode der Klasse A überlädst (overload), dann würde ObjektB.doSomething() auf die von Klasse B überladene Funktion (bzw. deren Implementierung) zurückgreifen und nicht auf die von Klasse A. Soweit zur Vorbereitung - nun zu deiner Frage: Eine Möglichkeit wäre, dass du einen cast machst. Möglichkeit zwei müsste in etwa so gehen: package forum; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; public class ClassHierarchy { public static void main(String[] args) { ArrayList<List> list = new ArrayList<List>(); list.add(new LinkedList()); list.add(new ArrayList<String>()); System.out.println(list.get(0).getClass()); System.out.println(list.get(1).getClass()); } } Die erste Ausgabe würde angeben, dass es sich um eine LinkedList handelt während die zweite Ausgabe ein ArrayList angeben würde - alles klar ? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
geloescht_Newlukai Geschrieben 17. Januar 2008 Teilen Geschrieben 17. Januar 2008 public A getMe(int num){ return (A) (foo.get(num)); } Mein Problem das ich damit habe, ist dass die Vererbungshierarchie mir hier irgendwie verloren geht. Wenn ich jetzt die getMe Methode verwende, dann kann ich immer nur das doSomething() von Klasse A aufrufen, nicht aber das von Klasse B auch wenn das Objekt von der Klasse B ist... Rein theoretisch(!) sollte das aber funktionieren. Da ich allerdings auch weiß, daß Du das wohl nicht posten würdest, wenn Du es nicht geprüft hättest, würde ich sagen: Laß' doch mal den Cast da weg. Du hast doch eine List, die Du mit Generics schon "typisiert" hast. Da ist der Cast doch unnötig. Vll. hilft das ... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Abd Sabour Geschrieben 17. Januar 2008 Teilen Geschrieben 17. Januar 2008 Rein theoretisch(!) sollte das aber funktionieren. Da ich allerdings auch weiß, daß Du das wohl nicht posten würdest, wenn Du es nicht geprüft hättest, würde ich sagen: Laß' doch mal den Cast da weg. Du hast doch eine List, die Du mit Generics schon "typisiert" hast. Da ist der Cast doch unnötig. Vll. hilft das ... Mhhh also wenn er auf A casted braucht er sich auch nicht wundern, wenn die Methode von Objekt A aufgerufen wird . Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
geloescht_Newlukai Geschrieben 17. Januar 2008 Teilen Geschrieben 17. Januar 2008 Mhhh also wenn er auf A casted braucht er sich auch nicht wundern, wenn die Methode von Objekt A aufgerufen wird . Objekte werden in Java nicht gecasted. Eigentlich werden nur die Referenzen gecasted. Daher wundert er sich zu recht ... Aber: Ich hab's jetzt selbst getestet: public class A { private int a; public A(int a) { setA(a); } public void setA(int a) { this.a = a; } void doSomething(){ System.out.println("do Something - class A: " + a); } } public class B extends A { public B(int a) { super(a); } void doSomething(){ System.out.println("do Something - class B"); } } import java.util.ArrayList; public class Test { ArrayList<A> bar = new ArrayList<A>(); public Test() { bar.add(new A(3)); bar.add(new B(4)); } public A getCasted(int num){ return (A) (bar.get(num)); } public A getUncasted(int num){ return bar.get(num); } public static void main(String args[]) { ArrayList<A> foo = new ArrayList<A>(); foo.add(new A(1)); foo.add(new B(2)); System.out.println("For each"); for(A a : foo) { a.doSomething(); } System.out.println("direkter Zugriff"); foo.get(0).doSomething(); foo.get(1).doSomething(); System.out.println("gecasteter Zugriff"); ((A) foo.get(0)).doSomething(); ((A) foo.get(1)).doSomething(); Test test = new Test(); System.out.println("direkter Zugriff über Methode"); test.getUncasted(0).doSomething(); test.getUncasted(1).doSomething(); System.out.println("direkter Zugriff über castende Methode"); test.getCasted(0).doSomething(); test.getCasted(1).doSomething(); System.out.println("A-Objekt aus nicht castender Methode"); A a1 = test.getUncasted(0); a1.doSomething(); A a2 = test.getUncasted(1); a2.doSomething(); System.out.println("A-Objekt aus castender Methode"); a1 = test.getCasted(0); a1.doSomething(); a2 = test.getCasted(1); a2.doSomething(); } } Und folgende Ausgabe bekomme ich: For each do Something - class A: 1 do Something - class B direkter Zugriff do Something - class A: 1 do Something - class B gecasteter Zugriff do Something - class A: 1 do Something - class B direkter Zugriff über Methode do Something - class A: 3 do Something - class B direkter Zugriff über castende Methode do Something - class A: 3 do Something - class B A-Objekt aus nicht castender Methode do Something - class A: 3 do Something - class B A-Objekt aus castender Methode do Something - class A: 3 do Something - class B Also bei mir läuft alles wie erwartet. Vielleicht postet Du einfach mal Deinen echten Quellcode bzw. vielleicht fällt Dir ein Schritt auf, den Du vergessen hast zu erwähnen? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Abd Sabour Geschrieben 17. Januar 2008 Teilen Geschrieben 17. Januar 2008 Also bei mir läuft alles wie erwartet. Vielleicht postet Du einfach mal Deinen echten Quellcode bzw. vielleicht fällt Dir ein Schritt auf, den Du vergessen hast zu erwähnen? Ich denke es liegt an dem, was ich bereits anfangs erwähnt habe: Er hat bei seinen beiden doSomething Methoden "do Something - class B" reingeschrieben - deshalb sieht er natürlich immer nur "do Something - class B" egal ob die Methode von A oder B aufgerufen wird .... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
geloescht_Newlukai Geschrieben 17. Januar 2008 Teilen Geschrieben 17. Januar 2008 Ich denke es liegt an dem, was ich bereits anfangs erwähnt habe: Er hat bei seinen beiden doSomething Methoden "do Something - class B" reingeschrieben - deshalb sieht er natürlich immer nur "do Something - class B" egal ob die Methode von A oder B aufgerufen wird .... Wäre natürlich 'ne Erklärung Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
ksg9-sebastian Geschrieben 23. Januar 2008 Teilen Geschrieben 23. Januar 2008 Stimmt schon, Objekte werden nicht gecastet. Und aufgerufen wird die Methode in in der Hierarchie ganz unten steht. Wenn ein super()-Aufruf erfolgt geht's in der Hierarchie eins hoch, u.s.w. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.