# Designfragen (mehrfach extends)



## H2SO3- (1. Jan 2011)

Hi,

Hätte mal die Frage wie folgendes am besten gelöst werden kann. Die Frage geistert mir schon länger durch den Kopf. Es geht um mehrfach extends. Weiß zwar das dies in Java nicht möglich ist und bin generell auch zufrieden mit den erklärungen dennoch würde ich gerne wissen wie man folgendes gut machen kann.

Ich habe zwei basis klassen


```
public class Wasserbewohner{
      public void schwimmer(){
          // sehr komplexe methode zum schwimmen
      }
}

public class Lungenatmer{
       public void atmen(){
           // sehr komplexe methode um sauerstoff zu atmen
      }
}
```
aus diesen beidem classen möchte ich nun eine dritte erzeugen

```
public class Delphin extends Wasserbewohner, Lungenatmer{ }
```

Somit könnte mein Delphin sowohl schwimmen wie auch mit seinen Lungen atmen.
Da dies so in Java nicht geht, muss was anderes her.
Gehen würde es mit Interfaces. Jedoch müsste hier die Delphin klasse ja die beiden methoden schwimmen und atmen selber implementieren. Ist doof da Delphin genauso atmet wie alle anderen Lungenatmer und genauso schwimmen soll wie alle anderen Wasserbewohner.

Eine möglichkeit hierfür könnte folgendes sein. Aber besonders toll finde ich es nicht, jedoch hätte es den vorteil, das der code zentral liegt und von allen erweiterungen von Wasserbewohnern und Lungenatmern benutzt werden kann. Je nachdem was sie sind. Ein Pferd muss ja atmen aber nicht schwimmen genauso wie ein Hai schwimmen aber nicht atmen muss (halt nicht mit Lunge).



```
public interface Wasserbewohner{
      public void schwimmer();
}

public interface Lungenatmer{
       public void atmen();
}

public class Schwimmen{
      public static void schwimmen(){
          // sehr komplexe methode zum schwimmen
       }
}
public class Atmen{
       public static void atmen(){
           // sehr komplexe methode um sauerstoff zu atmen
      }
}
public class Delphin implements Wasserbewohner, Lungenatmer{ 
       public static void schwimmen(){
          Schwimmen.schwimmen();
       }
       public static void atmen(){
           Atmen.atmen();
      }
}
```

Hoffe mal hier kennt jemand eine gute Designidee. Bin mit sicherheit nicht der erste der sowas machen will.


----------



## maki (1. Jan 2011)

Interfaces & abstrakte Basisklassen, du hast übrigens das ideale Beispiel dafür gewählt, würde gern mal sehen wie du ein Platypus umsetzen wolltest mit deiner jetztigen Idee von extends


----------



## H2SO3- (1. Jan 2011)

Bin mir nicht ganz sicher wie du das mit einer abstrakten basisklasse besser lösen willst. Eine alleine reicht ja auch hier wohl nicht.
Kannst du vielleicht ein minibeispiel geben.
Übrigens ein Platypus schwimmt doch genauso wie ein Fisch. (Zumind. wenn ich als Programierer es so definiere *gg*)

(Kann im moment nur selten ins netz also nicht wundern wenn die antwort etwas dauert)


----------



## maki (1. Jan 2011)

Abstrakte Basisklassen nur da wo es geht, ansonsten Interfaces.

Was du willst geht so nicht in Java, es gibt keine Mehrfachvererbung welche die Implementierung vererbt, nur die Schnitstellen, das ist ein Vorteil wenn man ihn man verstanden hat.

Ein Platypus hat einen Schnabel, Schwimmhäute, legt Eier in ein Nest auf dem trockenen, aber findet seine Nahrung im Wasser, wird offiziell als Säugetier geführt 

Interfaces bieten hier die flexibilität dass man bestimmte Eigenschaften bzw. Möglichkeiten getrennt definieren und trotzdem von ein und derselben Klasse implementieren lassen kann.
Ein extends impliziert dass viel mehr, eine "ist ein" Beziehung, Interfaces dagegen bedeutet ein "kann".

Vererbung ist nicht dafür da Code zu sparen oder Code wiederzuverwenden wo es "praktisch" aber nicht wirklich logisch ist, extends impliziert die stärkste Kopplung überhaupt.
Interfaces sind immer noch loser, Code lässt sich auch wiederverwenden bzw. Redundanz lässt sich vermeiden zB. durch delegation an Utility Methoden oder Klassen/Objekte die sich um spezifische Dinge kümmern, wie zB. das schwimmen.


----------



## Landei (1. Jan 2011)

Theoretisch könnte man zwei Interfaces und zwei Klassen, die das Interface implementieren nehmen, und mittels DynamixProxy daraus eine Klasse zusammenschustern. Der InvocationHandler muss halt zwei Instanzen der implementierenden Klassen mitbekommen, und jeweils die Methodenaufrufe geeignet delegieren. Wäre aber ziemlich unschön, und hätte schlechte Performance. Mittels Bytecode-Manipulation ginge es bequemer. 

Aber es stellt sich immer die Frage, ob man soetwas wirklich braucht, oder ob man sich nur beim Design nicht genügend Mühe gegeben hat.


----------



## DarkLegend (1. Jan 2011)

Hm noch nie wirklich damit zu tun  gehabt, aber finde ich sehr interessant 

Spontan würde bei mir sowas bei rauskommen: Quasi eine Kombination von abstrakten Klassen und Interfaces. 


```
public abstract WasserLebewesen {
    public SauerStoffOrgan sauerStoffOrgan;
    public WasserFortbewegung fortbewegung;

    public Lebewesen( SauerStoffOrgan sso, WasserFortbewegung wf) {
       [...]
    }

    public void schwimmen() {
       fortbewegung.schwimmen();
    }

    public void atmen() {
       sauerStoffOrgan.atmen();
    }
}

public interface WasserFortbewegung{
      public void schwimmen();
}
 
public interface SauerStoffOrgan{
       public void atmen();
}
 
public class Schwimmen implements WasserFortbewegung{
      public void schwimmen(){
          // sehr komplexe methode zum schwimmen
       }
}
public class Lunge implements SauerStoffOrgan{
       public void atmen(){
           // sehr komplexe methode um sauerstoff zu atmen
      }
}
public class Delphin extends WasserLebewesen{ 
      public Delphin() {
          super(new Lunge(), new Schwimmen() );
      }
}
```


----------



## Landei (1. Jan 2011)

Es heißt ja immer "Komposition statt Vererbung". Trotzdem bleibt das Problem, dass dein Delphin die anderen Interfaces nicht implementiert, also nicht an deren Stelle verwendet werden kann - was je nach Design das ganze wenig nützlich werden läßt.


----------



## DarkLegend (1. Jan 2011)

stimmt... den Aspekt an der Sache habe ich noch garnicht gesehen  Wobei man dem Wasserlebewesen die Interfaces eigentlich auch mitgeben könnte...


----------



## Herr K. (1. Jan 2011)

Hallo H2SO3-,

Dein Ansatz ist soweit eigentlich korrekt. An sich kannst Du hier einfach den Aufruf delegieren. Allerdings sollten die Klassen Schwimmen und Atmen die zugehörigen Interfaces implementieren. Damit stellst Du sicher, dass die Signatur und der Rückgabewert konsistent zu Änderungen am Interface gehalten werden (und Du kannst sinnvoll in der Dokumentation auf eben diese Methode verweisen).

Um Dein Leben etwas zu vereinfachen könntest Du als nächstes auf DI (Depency Injection) setzen und Dir die jeweilige Implementierung injezieren lassen (losere Kopplung), alternativ eine Fabrik verwenden, welche Dir eben die Standardimplementierung respektive ein Exemplar der Standardimplementierung zurück gibt. 

Hast Du nun auch noch eine Sammlung von Meeressäugern, dann bietet sich hier eine abstrakte Basisklasse an, welche eben die beiden Interfaces implementiert und damit auch die Delegation vereinheitlicht. 

Desweiteren solltest Du prüfen, ob Du Dein Objektdesign anpassen solltest. Du beschränkst Dich hier sehr stark auf die Vererbung um ein bestimmtes Verhalten wiederzuverwenden. Das Ziel der Vererbung liegt aber vor allem in der Abstraktion und Austauschbarkeit. 
Ein Lungenatmer klingt hier etwas zu speziell. Ohne nähere Kenntnis der Fachlichkeit würde ich sagen, dass sich eher ein Interface "Atmer" anbietet und eben die Implementierungen Lungenatmer, Hautatmer und Kiemenatmer (oder was es sonst so gibt) festlegen wie die Methode "atmen()" genau implementiert wird. 

Hier kann es sich dann anbieten, dass Du einfach auf Atmen und Fortbewegen als Interfaces abstrahierst und verschiedene Basisimplementierungen anbietest (für Atmen hatten wir das schon, für das Fortbewegen dann eben schwimmen, laufen und fliegen). 
Jedes Lebewesen hat nun jeweils eine Art zu atmen und eine sich fortzubewegen. In dem Fall kannst Du dann auch die Delegation in eine Basisklasse stecken:

```
public interface IAtmen {
  public void atmen();
}

public interface IBewegen {
  public void bewegen();
}

public abstract class Lebewesen implements IAtmen, IBewegen {
  private IAtmen atmen;
  private IBewegen bewegen;
  
  public void setAtmen(IAtmen atmen) {
    this.atmen = atmen;
  }
  
  public void setBewegen(IBewegen bewegen) {
    this.bewegen = bewegen;
  }
  
  public void bewegen() {
    if (this.bewegen == null) {
      throw new InitializationException("...");
    }
    
    this.bewegen.bewegen();
  }
  
  public void atmen() {
    if (this.atmen == null) {
      throw new InitializationException("...");
    }
    
    this.atmen.atmen();
  }
}
```

Zu den Interfaces kannst Du jetzt jeweils eigene Implementierungen erzeugen, ich sage einfach mal es gibt LungenAtmer und KiemenAtmer, sowie die Flieger und die Schwimmer. Eine Klasse Fisch (Schwimmer und Kiemenatmer) kann jetzt von der Basisklasse Lebewesen abgeleitet werden, wobei sichergestellt werden muss, dass die Implementierungen über die Setter implementiert werden. Hierbei kannst Du auf das Builderpattern zurückgreifen:

```
public class LebewesenBuilder {
  private Lebewesen lebewesen;

  public LebewesenBuilder(final Lebewesen lebewesen) {
    this.lebewesen = lebewesen;
  }

  public LebewesenBuilder setLungenatmer() {
    this.lebewesen.setAtmer(new LungenAtmer());
    return this;
  }

  public LebewesenBuilder setKiemenatmer() {
    this.lebewesen.setAtmer(new KiemenAtmer());
    return this;
  }

  public LebewesenBuilder setSchwimmer() {
    this.lebewesen.setBewegen(new Schwimmer());
    return this;
  }

  public LebewesenBuilder setFlieger() {
    this.lebewesen.setBewegen(new Flieger());
    return this;
  }

  public Lebewesen build() {
    return this.lebewesen;
  }
}
```

Jetzt kannst Du die Implementierungen sehr einfach im Konstruktor der jeweiligen Implementierung vornehmen.

```
public class Fisch extends Lebewesen {
  public Fisch() {
    new LebewesenBuilder(this).setSchwimmer().setKiemenatmer();
  }
}

public class Vogel extends Lebewesen {
  public Fisch() {
    new LebewesenBuilder(this).setFlieger().setLungenatmer();
  }
}
```


----------



## Noctarius (1. Jan 2011)

Man kann auch häufig genutzt Implementierungen in Utility-Klassen auslagern und dann in den implementierenden Klassen aufrufen.


```
public class AtemUtils {
  private AtemUtils() { }

  public static void atem(Atem atem) {
    atem.atmen();
  }
}

public class Delphin extends Wasserbewohner, Lungenatmer{
  private final Atem atem = new Atem();

  public void atmen() {
    AtemUtils.atmen(atem);
  }
}
```

So braucht man gleiche Implementierungen nicht mehrfach kopieren. Code-Doppler sind auch unschön


----------



## Herr K. (1. Jan 2011)

@Noctarius:
So wie bereits im ersten Post enthalten? Die Frage zielt ja gerade darauf ab, ob man das nicht schöner machen kann...


----------



## Noctarius (1. Jan 2011)

Herr K. hat gesagt.:


> @Noctarius:
> So wie bereits im ersten Post enthalten? Die Frage zielt ja gerade darauf ab, ob man das nicht schöner machen kann...



Oh ich hatte übersehen, dass Atem schon eine Utility-Class ist.


----------

