# Design Pattern zur Realisierung von Mehrfachvererbung?



## -frank (9. Apr 2007)

Ich hab eine abstrakte Klasse AbstractA. Davon abgeleitet sind 6 Klassen A1 bis A6 (namen natürlich nur als Beispiel).
Nun nutze ich diese 6 Klassen in einem anderen Teil des Programms und benötige dafür Erweiterungen -->
B1..B6 extends A1..A6

da es in vielen Fällen es nicht wichtig ist, ob B1 oder B6 ist (sondern einfach nur ein B sein muss), kann man sich schon denken, dass es hier sehr viel gemeinsamkeiten gibt, die ich am liebsten in einer Klasse AbstractB zusammenfassen würde. Dass Mehrfachvererbung nicht möglich ist in Java vieles verkomplizieren würde, ist mir klar. Ich frage mich nun aber, wie man das ganze trotzdem (am besten) lösen kann. Gibt es dafür ein spezielles Design Pattern?

meine ansatz wäre gewesen, dass ich ein Interface B mache. dieses definiert den Kopf aller gemeinsam Methoden der B-Klassen. soweit so gut. Das löst die Verwendung von B-Objekten perfekt, aber nicht deren Implementierung:
das Problem ist nun, dass ich sehr viel gemeinsamen Code habe, sprich gerne ganze Methoden hinzufügen würde. Dazu würde ich nun eine Klasse BHelper machen, welche statische Methoden zur Verfügung stellt, um auf B-Objekten zu operieren.
in den B-Klassen habe ich dann zb eine vom B-Interface vorgegebene Methode

```
boolean doSomething(Object obj)
```
und diese wird zu

```
boolean doSomething(object obj) {
    return BHelper.doSomething(this, obj);
}
```

diese Methode muss dann natürlich in jede B-Klasse, aber immerhin ist der eigentliche Code in BHelper und somit nicht redundant.

meine zweite, recht ähnliche überlegung: die Vererbung von A auf B sieht so aus, dass B A erweitert in dem es weitere Felder hinzufügt und weitere Methoden. Ich könnte die Vererbung auch streichen (was eine abstrakte Klasse AbstractB ermöglichen würde) und dafür jedem B1..B6 Objekte ein A1..A6 (im Konstruktor) übergeben. dann müsste ich jede Methode von A in B implementieren, in dem ich sie an das A-Objekt weiterleite.


```
int doSomethingElse(Object obj) {
    return this.a.doSomethingElse(obj)
}
```

gibt es eine dritte möglichkeit?

worauf basierend sollte ich die entscheidung zwischen Variante 1 und 2 treffen?
vermutlich würde bei mir Variante 2 die B Objekte sehr verkomplizieren, andererseits hätte ich kein Hilfsobjekt B-Helper, welches für das funktionieren von B notwendig ist...


----------



## norman (10. Apr 2007)

-frank hat gesagt.:
			
		

> meine zweite, recht ähnliche überlegung: die Vererbung von A auf B sieht so aus, dass B A erweitert in dem es weitere Felder hinzufügt und weitere Methoden. Ich könnte die Vererbung auch streichen (was eine abstrakte Klasse AbstractB ermöglichen würde) und dafür jedem B1..B6 Objekte ein A1..A6 (im Konstruktor) übergeben. dann müsste ich jede Methode von A in B implementieren, in dem ich sie an das A-Objekt weiterleite.
> 
> 
> ```
> ...



Fast. Leite deine abstrakte B-Klasse von A ab. du musst aber nicht  alle abstrakten methoden von A in B überschreiben, weil B ja auch abstrakt ist. das musst du erst in der konkreten implementierung machen. nur, was für alle Bs gleich ist, implementierst du auch in B.


```
public abstract class A {
	public abstract void doSth();
}

public abstract class B extends A {
	protected abstract void doSthElse();
}

public class ImplOfB extends B {

	@Override
	public void doSth() {
		
	}

	@Override
	protected void doSthElse() {
		
	}
}
```


----------



## -frank (10. Apr 2007)

norman hat gesagt.:
			
		

> Fast. Leite deine abstrakte B-Klasse von A ab. du musst aber nicht  alle abstrakten methoden von A in B überschreiben, weil B ja auch abstrakt ist. das musst du erst in der konkreten implementierung machen. nur, was für alle Bs gleich ist, implementierst du auch in B.



hmmm. ja, ich überleg(t)e, ob diese verebung für mich sinn macht. der vorteil wäre natürlich, dass automatisch jede eigenschaft von A auch von B und damit B1..B6 erfüllt wird. Allerdings kann ich die Methoden von A1..A1 so nicht vererben.
ich denke, es ist besser, wenn ich ein Interface A mache und dieses einfach von AbstractB nochmal implementieren lasse (anstatt direkt von AbstractA zu erben). zur implementierung der methoden nehme ich einfach ein A Objekt:

```
public doSomething() {
    getA().doSomething();
}
```

so habe ich zwar etliche solcher methoden, aber es sind ja immer nur 3-zeiler. der vorteil ist, dass ich mithilfe des A objekts dann auch die Methoden von A1..A6 mit 3-zeilern implementieren kann während ich diese methoden ohne ein solches objekt vollständig implementieren müsste:


```
public doSomethingElse() {
    ((A1)getA()).doSomethingElse();
}
```

diese kurzen methoden sind schnell geschrieben und kaum fehleranfällig. als großen nachteil sehe ich allerdings, dass eine methode aus A, die auf eine andere A-Methode zugreift, dann natürlich die Methode aus dem A-Objekt nimmt, während ich bei deiner Variante diese A Methode überschreiben könnte und dann die überschriebene Methode aufgerufen würde.

--> also vermutlich kommts da sehr stark auf die spezielle situation an und was man braucht.

danke auf jeden fall!
(falls du oder andere noch mehr nachteile bei meiner variante sehen, würde es mich freuen, wenn ihr sie mir mitteilt  )


----------



## norman (11. Apr 2007)

-frank hat gesagt.:
			
		

> Allerdings kann ich die Methoden von A1..A1 so nicht vererben.



sagt wer?

wenn B von A erbt, dann hat B1 alle methoden/ felder von B und genauso alle von A (sofern sie nicht schon von B überschrieben wurden).

natürlich nur wenn die methoden/felder protected oder mehr sind.


----------



## -frank (11. Apr 2007)

norman hat gesagt.:
			
		

> wenn B von A erbt, dann hat B1 alle methoden/ felder von B und genauso alle von A (sofern sie nicht schon von B überschrieben wurden).
> 
> natürlich nur wenn die methoden/felder protected oder mehr sind.



das ist schon klar. aber - ich weiß nicht, ob es aus meinem erst post kalr genug hervorgeht - jedes B1 braucht alle Methoden von A1, jedes B2 alle von B2, etc. und diese methoden bekomme ich dann nicht.


----------



## norman (11. Apr 2007)

okay, jetzt hab ichs auch  sorry..

dann erbt B1 von A1 und B2 von A2 usw usf und alle Bs implementieren ein Interface.
in den implementieren methoden in den Bs kannst du ja dann auch ein BHelper verweisen.


```
class B1 extends A1 implements BInterface {
  @override
  public void bInterface_doSth() {
    BHelper.doSth();
  }
}
```

was besseres weiß ich auch nicht /


----------



## -frank (11. Apr 2007)

norman hat gesagt.:
			
		

> was besseres weiß ich auch nicht /



also ich hab noch ein bisschen rumgegooglet und es scheint auch nichts besseres zu geben. danke auf jeden fall!
ich habs jetzt allerdings umgekehrt gemacht, also B1 erbt von B und implementiert das Interface A1.
was ich so gelesen habe, sind beide varianten in ordnung. kommt dann halt auf die menge des codes an, welcher code sich öfter verändert, etc.


----------



## norman (11. Apr 2007)

okay, dann viel erfolg noch!


----------



## -frank (11. Apr 2007)

norman hat gesagt.:
			
		

> okay, dann viel erfolg noch!



danke 

(ich lasse die "gelöst" markierung bewusst noch weg, fr den fall, dass noch jemand einen tipp haben sollte. denke aber, dass es so klappen wird)


----------

