Zum Inhalt springen

ArrayList zugriff und Generalisierung/Spezialisierung


Rain

Empfohlene Beiträge

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 (B) 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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 :) ?

Link zu diesem Kommentar
Auf anderen Seiten teilen


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 ...

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 :P.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mhhh also wenn er auf A casted braucht er sich auch nicht wundern, wenn die Methode von Objekt A aufgerufen wird :P.

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?

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 ....

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 :D

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...