Double Dispatch mit abstrakter Klasse

Benutzeravatar
sproksch
Computerversteher
Computerversteher
Beiträge: 346
Registriert: 15. Apr 2004 17:56

Double Dispatch mit abstrakter Klasse

Beitrag von sproksch » 13. Nov 2008 15:58

Ich fand den Einwurf in der heutigen Vorlesung "Warum wird beim Double Dispatch keine abstrakte Klasse verwendet?" interessant, da ich es mir selbst nicht erklären konnte. Ich habe aus dem Grunde mal ein einfaches Beispiel in Anlehnung an die Folien gemacht, das versucht dieses Problem mit einer abstrakten Klasse zu lösen. Die abstrakte Klasse soll es mir ersparen, in jeder abgeleiteten Klasse die Methode intersect(Shape) implementieren zu müssen. Zur Kontrolle gebe ich die Klasse des übergebenen Objekts aus.

Code: Alles auswählen

public abstract class Shape {
	public void intersect(Shape s) {
		System.out.println("MyClass: " + this.getClass());
		s.intersect(this);
	}

	public abstract void intersect(Line l);
	public abstract void intersect(Circle c);

	public static void main(String[] args) {
		Shape c1 = new Circle();
		Shape c2 = new Circle();
		Shape l1 = new Line();
		Shape l2 = new Line();

		l1.intersect(l2);
		l1.intersect(c1);
		c1.intersect(l2);
		c2.intersect(c1);
	}
}

Code: Alles auswählen

public class Circle extends Shape {

	@Override
	public void intersect(Line l) {
		System.out.println("Circle.intersect(Line)");
	}

	@Override
	public void intersect(Circle c) {
		System.out.println("Circle.intersect(Circle)");
	}
}

Code: Alles auswählen

public class Line extends Shape {

	@Override
	public void intersect(Line l) {
		System.out.println("Line.intersect(Line)");
	}

	@Override
	public void intersect(Circle c) {
		System.out.println("Line.intersect(Circle)");
	}
}
Startet man dieses Programm, knallt es. :) Der interessante Punkt dabei ist die Ausgabe des Programms, er gibt die "richtige" Klasse aus, ruft aber die "falsche" Methode auf:

Code: Alles auswählen

MyClass: class Line
MyClass: class Line
... (etliche Wiederholungen)
und dann ein Stack Overflow
Ich habe mir dieses Verhalten nun so erklärt: Zur Compilezeit legt javac das Dispatching anhand des übergebenen Objekts fest, d.h. bei Aufruf der intersect(Shape) der abstrakten Klasse, wird erneut intersect(Shape) aufgerufen, in diesem Falle dann solange, bis der Stack voll ist. Erst zur Laufzeit kann ich dem Objekt die Information entnehmen, dass es sich um eine Line/Circle/whatever handelt und habe dann die Korrekte Ausgabe "MyClass: class Line".

Habe ich das ganze damit richtig verstanden, oder bin ich auf dem Holzweg?

maikg2
Mausschubser
Mausschubser
Beiträge: 95
Registriert: 18. Okt 2005 22:29
Wohnort: Darmstadt

Re: Double Dispatch mit abstrakter Klasse

Beitrag von maikg2 » 13. Nov 2008 16:54

Hallo,

kurz gesagt: Ja, du hast es richtig verstanden.
Für eine ausführliche Beschreibung empfehle ich den Thread aus dem letzten Jahr.

Gruß
Maik

Sebastian Hartte
Sonntagsinformatiker
Sonntagsinformatiker
Beiträge: 236
Registriert: 15. Apr 2004 17:57

Re: Double Dispatch mit abstrakter Klasse

Beitrag von Sebastian Hartte » 13. Nov 2008 17:30

Ich glaube am besten lässt sich das Problem durch folgenden Codeschnipsel darstellen:

Quiz: Was gibt dieses Programm aus?

Code: Alles auswählen

public class DispatchDemo {
	public static void doSomething(A a) {
		System.out.println("A");
	}
	
	public static void doSomething(B b) {
		System.out.println("B");
	}
	
	public static void main(String[] args) {
		A obj = new B();
		doSomething(obj);
	}	
}

class A {	
}

class B extends A {	
}
Gruß,
Sebastian

Antworten

Zurück zu „Archiv“