Polymorphie Knobelspaß ;-)

Status
Nicht offen für weitere Antworten.
Hallo Java-Kollegen!

Ich habe da ein Problemchen was ich nicht lösen kann:

In einer Liste befinden sich Elemente die ich entsprechend ihres Typs unterschiedlich behandeln will. Ich möchte Polymorphie benutzen, um mir verschachtelte Verzweigungen zu ersparen. Hat jemand eine Idee, wie sich das lösen lässt.

Hier mein Beispiel:

Code:
import java.util.ArrayList;
import java.util.List;


public class SmallTests {
	
	
	List<A> aList = new ArrayList<A>();

	public static void main(String[] args) {
		SmallTests t = new SmallTests();

		
		//Die Liste enthält Untertypen von A
		t.aList.add( t.new A1() );
		t.aList.add( t.new A2() );
		
		
		//In der Schleife soll eine Unterscheidung nach Untertyp erfolgen.
		//Dies führt aber leider zu einem Fehler des Compilers.
		//Euer Rat ist hier gefragt...
		for( A a : t.aList )
			test( a );
	}
	
	
	private static void test( A1 a ) {
		System.out.println( a.getClass().getName() );		
	}

	private static void test( A2 a ) {
		System.out.println( a.getClass().getName() );		
	}
	

	private class A {
		
	}
	
	private class A1 extends A {
		
	}
	
	private class A2 extends A {
		
	}

}


Vielen Dank

Stefan
 
M

maki

Gast
>> In einer Liste befinden sich Elemente die ich entsprechend ihres Typs unterschiedlich behandeln will

Falsch herum, die Objekte sollen sich unterschiedlich (ja nach Typ) verhalten, Schnittstellen sollten dieselbe sein.

D.h.: Defniere eine abstrakte Methode in Klasse A (muss dann auch abstrakt sein) die von A1 und A2 implementiert wird.
 

ARadauer

Top Contributor
das ist polymorphie...

Code:
import java.util.ArrayList;
public class Test  {
   
   public static void main(String[] args) {
     ArrayList<Tier> tiere = new ArrayList<Tier>();
     tiere.add(new Katze());
     tiere.add(new Hund());
     tiere.add(new Hund());
     tiere.add(new Katze());
     
     for(Tier t: tiere)
        t.gibLaut();      
   }  

}

interface Tier{
   public void gibLaut();
}

class Hund implements Tier{
   @Override
   public void gibLaut() {
      System.out.println("wau wau");         
   }      
}

class Katze implements Tier{
   @Override
   public void gibLaut() {
      System.out.println("mia mia");         
   }      
}
die implementierungen entscheiden selbst über ihre verhalten, sie werden über eine gemeinsame schnittstelle (kann auch eine überklasse sein) angesprochen...
 
M

maki

Gast
>> Mein Beispiel kann man nicht zum laufen bekommen, nehme ich an?

Dein Beispiel nutzt keine Polymorphy, also kannst du damit in dieser Form keine Polymorphy zeigen.
 
maki hat gesagt.:
>> Mein Beispiel kann man nicht zum laufen bekommen, nehme ich an?

Dein Beispiel nutzt keine Polymorphy, also kannst du damit in dieser Form keine Polymorphy zeigen.

....uuund grundsätzlich kann man auch keine Elemente aus einer Object-Liste holen und die dann dynamisch irgendwie casten, so dass das Beispiel von mir funktioniert ?

Vielen Dank schon mal an alle Beteiligten!

Stefan
 
M

maki

Gast
>> ..uuund grundsätzlich kann man auch keine Elemente aus einer Object-Liste holen und die dann dynamisch irgendwie casten, so dass das Beispiel von mir funktioniert ?

Was denn für ein Beispiel??? ;)

Du hast eine Klasse mit 3 statischen Methoden, das einzige was vererbt werden könnte ist aList, sonst nix.

Wieso nimmst du die Ratschläge nicht an und schreibst die abstrakten Methoden?
 
maki hat gesagt.:
Wieso nimmst du die Ratschläge nicht an und schreibst die abstrakten Methoden?

Das geht schon klar. Die Ratschläge waren auch gut und haben meine Gedanken geordnet. Ich habe es ja jetzt auch anders gelöst.

Mein Problem besteht darin das ich immer zwei Objekte betrachten muss, die entweder vom Typ A1 oder A2 sind. Dabei kommt es unter anderem darauf an, welches zuerst kommt. Und je nachdem welches zuerst kommt, muss ich Diese beiden Kollegen anders behandeln.

Code:
private static void test( A1 a1, A2 a2 ) {
    //Mach was mit a1 und a2
}

private static void test( A2 a2, A1 a1 ) {
    //Mach was anderes mit a1 und a2
}

...
//Noch weitere Fälle

Es hätte halt eleganter ausgesehen, wenn sich das so lösen ließe. Es geht aber auch anders.

Viele Grüße

Stefan
 
M

maki

Gast
>> ..und haben meine Gedanken geordnet.

Unwahrscheinlich, immer noch keine Polymorphy, höchstens sinnfreie Vererbung ;)
 

ARadauer

Top Contributor
schau dir mal das Strategy Pattern an... hab jetzt keine lust das zu erklären, aber das könntest du einsetzen
 

Ariol

Top Contributor
Man könnte das per Reflection lösen:

Code:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class SmallTests
{

	List<A>	aList	= new ArrayList<A>();

	public static void main(String[] args)
	{
		SmallTests t = new SmallTests();

		// Die Liste enthält Untertypen von A
		t.aList.add(t.new A1());
		t.aList.add(t.new A2());

		// In der Schleife soll eine Unterscheidung nach Untertyp erfolgen.
		// Dies führt aber leider zu einem Fehler des Compilers.
		// Euer Rat ist hier gefragt...
		for (A a : t.aList)
		{
			try
			{
				test(a);
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
	}

	private static void test(A a) throws Exception
	{
		Class c = Class.forName(SmallTests.class.getName());
		Method m[] = c.getDeclaredMethods();
		for (int i = 0; i < m.length; i++)
		{
			if (m[i].getName().equals("test") && m[i].getParameterTypes()[0].equals(a.getClass()))
			{
				m[i].invoke(null, new Object[]
				{ a });
			}
		}

	}

	private static void test(A1 a)
	{
		System.out.println("A1");
		System.out.println(a.getClass().getName());
	}

	private static void test(A2 a)
	{
		System.out.println("A2");
		System.out.println(a.getClass().getName());
	}

	private class A
	{

	}

	private class A1 extends A
	{

	}

	private class A2 extends A
	{

	}

}
 

Marco13

Top Contributor
dangermouse78 hat gesagt.:
Mein Problem besteht darin das ich immer zwei Objekte betrachten muss, die entweder vom Typ A1 oder A2 sind. Dabei kommt es unter anderem darauf an, welches zuerst kommt. Und je nachdem welches zuerst kommt, muss ich Diese beiden Kollegen anders behandeln.

Wie und wann werden diese Methoden denn aufgerufen? Wenn ich das richtig verstanden habe, hast du ja sowas wie
Code:
List<A> list =...

list.add(new A1());
list.add(new A2());

test(list.get(0), list.get(1));
und in dem Fall soll ein anderes "test" aufgerufen werden, als wenn man
Code:
list.add(new A2());
list.add(new A1());
gemacht hätte?

Wer entscheidet, in welcher Reihenfolge die Objekte in die Liste gelegt werden? Kann der nicht auch entscheiden, welche Methode aufgerufen werden soll? Sollte es vielleicht (in Anlehnung an den Vorschlag mit dem StrategyPattern) etwas geben, was über eine Liste hinausgeht, und eben nicht nur die Elemente speichert, sondern auch über ihre Reihenfolge und ihre unterschiedliche Behandlung bescheid weiß?
 
G

Guest

Gast
Ariol hat gesagt.:
Man könnte das per Reflection lösen:

nichts für ungut, aber warum postet eigentlich immer jemand ne reflection lösung um irgendnem anfänger bei seinem problem zuhelfen

man kann "alles" mit reflection lösen, nur in diesem fall ist doch eindeutig das der fragesteller nicht weiss wie man richtig an das problem ran geht

ausserdem wäre instanceof wohl am sinnvollsten (Wenns denn unbedingt ohne polymorphie sein soll)
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben