# Verhalten über Interfaces ergänzen



## White_Fox (19. Jun 2019)

Annahme:
Es gebe eine (meinetwegen abstrakte) Klasse Landfahrzeuge, aus der mehrere Klassen abgeleitet werden: Auto, Panzer, Motorad, Fahrad, usw.

Jetzt will ich das Verhalten einiger Klassen ändern und das Interface floatable implementieren, damit z.B. der Panzer auch schwimmen kann. Die Methode void swim(int destX, int destY) kann für alle Klassen gleich implementiert werden, also schreibe ich geschickterweise eine default-Methode. Soweit so gut.

Jetzt erfordert meine Implementierung aber die Speicherung der Methodenparameter, dies wiederum würde ich ja normalerweise über eine Instanzvariable machen. Und an dieser Stelle knallt das ganze Konzept, da in Interfaces ja keine Instanzvariablen liegen können.

Frage: wie kriegt man sowas dennoch elegant gelöst?
Klar, ich könnte die Methode einfach ohne Default realisieren, dann kann ich sie über schreiben und der konkreten Klasse nach Belieben Instanzvariablen einbauen. Dafür implementiere ich den Code aber zigmal auf identische Weise (und das zu Vermeiden war ja mein Ziel).

Was macht denn ein Java-Entwickler bei solchen Sachen?

Im konkreten Fall habe ich mein Konzept komplett geändert, und anstatt des Interfaces eine abstrakte Klasse gebaut. Das ging in diesem Fall ohne größere Schmerzen, aber was ist wenn das mal nicht geht? Im obigen Beispiel würde ich den Schwimmpanzer immer noch als vollwertiges Landfahrzeug ansehen, auch wenn er zufällig Schwimmen kann. Aber wie kriege ich dieses Problem dann aufgelöst?

Nachschlag: Oder hat das etwa einen tieferen Sinn, daß in Interfaces keine Instanzvariablen deklariert werden können, ähnlich wie warum Mehrfachvererbung nicht erlaubt ist?


----------



## Phash (19. Jun 2019)

Mit default-Methoden hab ich so mein Problem... ich mag sie noch nicht 
Es gibt eigentlich 2 Ansätze: entweder du machst abstrakte Klassen, die die Interfaces implementieren - hier scheiterst du jedoch, wenn du z.B. "kann fliegen" und "kann schwimmen" gleichzeitig erben willst - da wären Interfaces besser. 

Du könntest allerdings die unterschiedlichen Eigenschaften deines Fahrzeuges mit dem Decorator-Pattern bzw mit Composition over Inheritance lösen.

ich bastel mal was


----------



## mrBrown (19. Jun 2019)

Phash hat gesagt.:


> Mit default-Methoden hab ich so mein Problem... ich mag sie noch nicht


noch nicht? Sind ja auch grad mal fünf Jahre alt  Aber warum denn nicht?


----------



## temi (19. Jun 2019)

mrBrown hat gesagt.:


> noch nicht? Sind ja auch grad mal fünf Jahre alt  Aber warum denn nicht?



Ich mag sie auch nicht, meiner Ansicht nach wird dadurch das Konzept "Interface" irgendwie verwässert.

Vielleicht magst du mich ja von der Sinnhaftigkeit überzeugen?


----------



## mihe7 (19. Jun 2019)

White_Fox hat gesagt.:


> Was macht denn ein Java-Entwickler bei solchen Sachen?


Er ärgert sich, dass er nicht bei C++ geblieben ist  

Ansonsten s. Beitrag von @Phash, dazu auch https://de.wikipedia.org/wiki/Komposition_an_Stelle_von_Vererbung


----------



## White_Fox (19. Jun 2019)

Phash hat gesagt.:


> Du könntest allerdings die unterschiedlichen Eigenschaften deines Fahrzeuges mit dem Decorator-Pattern bzw mit Composition over Inheritance lösen.


Hm...die Verwendung eines Interfaces trägt doch dem Komposition-vor-Vererbung-Prinzip doch Rechnung (jedenfalls habe ich den Wiki-Artikel so verstanden), aber wie das mit dem Dekoratorf gehen soll würde ich gerne wissen.




temi hat gesagt.:


> Ich mag sie auch nicht, meiner Ansicht nach wird dadurch das Konzept "Interface" irgendwie verwässert.


Das versteh ich nicht so recht...die Bezeichnung "default" drückt ja schon aus, daß diese Methode keineswegs in Stein gemeißelt ist. Ich sehe da eigentlich nur eine Möglichkeit, in speziellen Fällen wie oben weniger Code schreiben zu müssen. Die Verwendung sehe ich ohne Instanzvariablen aber sehr eingeschränkt.


----------



## thecain (19. Jun 2019)

Angenommen du hast das interface floatable überall implementiert und willst es jetzt erweitern.
Nun müssen alle die das Interface implementieren dies auch tun. Mit einer default Implementierung kann dies verhindert werden.


----------



## mrBrown (19. Jun 2019)

temi hat gesagt.:


> Vielleicht magst du mich ja von der Sinnhaftigkeit überzeugen?


Sind halt die einzige Möglichkeit, Interfaces Kompatibel zu erweitern 
Und weiterhin enthalten Interfaces ja keinen Zustand, von daher sind die noch weit von Klassen entfernt.


----------



## temi (19. Jun 2019)

thecain hat gesagt.:


> Nun müssen alle die das Interface implementieren dies auch tun. Mit einer default Implementierung kann dies verhindert werden.



Das würde aber, ohne Instanzvariablen, nur sehr eingeschränkt funktionieren. Genau gesagt, nur unter Verwendung der bereits vorhandenen Interface-Methoden.

Oder ich verstehe das falsch.


----------



## White_Fox (19. Jun 2019)

Es würde zumindest die Möglichkeit geben, ein einfaches return standardValue; zu implementieren und das Programm weiter lauffähig zu halten.


----------



## Phash (24. Jun 2019)

Default-Methoden erlauben Mehrfachvererbung. Wir sind hier bei Java. Da wollen wir das nicht 

du könntest deinem Fahrzeug verschiedene "Fortbewegungsmöglichkeiten" geben. Jedes weiß, ob es fliegen, laufen, fahren oder schwimmen kann. Du fragst dein Fahrzeug: getFortbewegungsmöglichkeit(Fortbewegungsart.FLIEGEN) und das Fahrzeug schaut nach, ob es fliegen kann, oder gibt eben nix zurück - jede Fortbewgungsmöglichkeit implementiert dann "bewegen" oder so und du kannst das verwenden.
Dann musst du beim erstellen der Fahrzeuge halt angeben, welche Fortbewegungsmöglichkeiten sie haben (Behaviours)


----------



## mrBrown (24. Jun 2019)

Phash hat gesagt.:


> Default-Methoden erlauben Mehrfachvererbung. Wir sind hier bei Java. Da wollen wir das nicht


Allerdings nur von öffentlichen Methoden, und wenn es mehrere default-Methoden gibt, muss man zwingend überschreiben. Zu "echter" Mehrfachvererbung und deren Problemen fehlt da schon noch was


----------

