In Bezug auf OOP wird ja immer wieder gesagt, dass man möglichst Vererbung vermeiden sollte und stattdessen lieber auf die Verwendung von Interfaces zuürckgreifen sollte.
Mir persönlich ist aber nicht so ganz klar, warum Vererbung zu Problemen führen sollte und die Verwendung eines Interface hingegen nicht.
Kann mir da vielleicht jemand etwas zu sagen? Baue ich mir mit Vererbung einfach ein zu starres Gerüst für eine Applikation auf?
Genau, es wird "zu starr". Mit Vererbung legst du den Supertyp für deine Klasse schon fest und kannst ihn später auch nicht mehr ändern. Mit einem Interface bist du da wesentlich flexibler, da deine Klasse auch meheren Interfaces implementieren kann.
Zudem wird Vererbung manchmal auch missbraucht, indem sie in Situationen eingesetz wird, wo man auch einen Konstuktor normal aufrufen könnte.
Falsch:
Natürlich hat Vererbung auch seine Berechtigung und ist in vielen Situationen sehr sinnvoll. Java würde nicht so funktionieren wie es das tut, wenn es keine Vererbung gäbe.
Die Aussage ist in dieser Form mMn einfach Blödsinn!
Natürlich kann und sollte man auf Vererbung setzen, sofern es denn angebracht ist. Interfaces setzt du ein, um Schnittstellen nach außen zu definieren, Vererbung für die Spezialisierung eines Typs. Es widerspricht völlig dem OOP-Denken für jeden speziellen Typ alle Funktionalitäten separat implentieren zu müssen. Eine Änderung, die sich auf alle speziellen Typen auswirkt, sollte dann nur in der gemeinsamen Basisklasse notwendig sein.
Seit Java 8 haben wir zwar auch die Möglichkeit sogar in Interfaces konkrete default-Implementierungen mitzugeben, aber diese sind implizit dann immer public, was für die Schnittstelle nach außen hin natürlich schon eine große Einschränkung ist (Stichwort Kapselung und Information Hiding)
Interfaces sind eine Krücke für Mehrfachvererbungen. Da Mehrfachvererbungen aber eh immer sehr kritisch sind würde ich immer davon Abstand nehmen wenn es sich irgendwie vermeiden läßt.
Ansonsten schließe ich mich der Meinung von stg voll an. Interfaces waren und sind nicht dafür gedacht das OOP neu zu erfinden und Vererbung zu ersetzen. Gerade das alle Methoden Public sind führt das OOP sogar ad absurdum, wobei ich heutztage immer mehr beobachte, dass viele "Programmierer" sowiso alle Methoden als public deklarieren weil es ja viel einfacher ist, als sich vorher Gedanken über ein gutes Klassendesign zu machen.
Generell: Komposition ist Vererbung vorzuziehen.
Stell dir eine Spiel vor wo Spielfiguren schießen können. Du überschreibst nicht für jede Ausprägung die schießen Methode, sondern baust dir einfach Waffen und deine Spielfigur hat eine Referenz auf eine Waffe.
Dadurch ergibt sich im allgemeinen ein viel flexibleres Design.
Generell: Komposition ist Vererbung vorzuziehen.
Stell dir eine Spiel vor wo Spielfiguren schießen können. Du überschreibst nicht für jede Ausprägung die schießen Methode, sondern baust dir einfach Waffen und deine Spielfigur hat eine Referenz auf eine Waffe.
Dadurch ergibt sich im allgemeinen ein viel flexibleres Design.
Da kann ich Dir nicht folgen. In Deinem Beispiel hätte ich eine Klasse Spieler der eine property Waffe (oder auch WaffenArray) hat und ich hätte eine Klasse Waffe. wo brauche ich da jetzt Vererbung oder Interfaces?
@Claus
Gar nicht. Darauf wollte er ja hinaus. In Vielen Fällen ist es besser auf Komposition statt auf Vererbung zu setzen, insbesondere in Hinblick auf Lose Kopplung. Dem ist natürlich im Allgemeinen zuzustimmen, aber meine Aussage von oben bleibt dadurch eigentlich unberührt. Vererbung wird oft falsch eingesetzt, aber das ändert nichts daran, dass das Konzept grundsätzlich sinnvoll ist und seine Daseinsberechtigung hat.
@Claus
Gar nicht. Darauf wollte er ja hinaus. In Vielen Fällen ist es besser auf Komposition statt auf Vererbung zu setzen, insbesondere in Hinblick auf Lose Kopplung. Dem ist natürlich im Allgemeinen zuzustimmen, aber meine Aussage von oben bleibt dadurch eigentlich unberührt. Vererbung wird oft falsch eingesetzt, aber das ändert nichts daran, dass das Konzept grundsätzlich sinnvoll ist und seine Daseinsberechtigung hat.
Ich finde es auch schwachsinn, auf Vererbung zu verzichten. Um gerade nochmal das Beispiel mit den Waffen aufzugreiffen. Es gibt Klingen-Waffen und Feuerwaffen. Eine Pistole ist eine Feuerwaffe, genauso wie ein Gewehr. Beide haben einen Abzug, der (von wem auch immer) betätigt werden kann. Ein Katana ist zwar auch eine Waffe (ebenso wie die Pistole und das Gewehr), aber um es einzusetzen ist das simple betätigen eines Abzugs lange nicht genug.
Ich denke, Vererbung sollte überall dort eingesetzt werden, wo Eingeschaften und Funktionalitäten (abstrahiert) zusammengefasst werden können. Das alles sollte man aber sehr klein Modular aufbauen (wie ARadauer schon sagte), um die einzelnen Komponenten ohne veränderung am bestehenden Code erweitern und/oder austauschen zu können: Wenn der Spieler eine Methode
Code:
schießen
hat, dann aber ein Katana verwenden soll muss man umbauen. Hat der Spieler hingegen eine Methode
Code:
angreiffen
(oder noch besser
Code:
angreiffen(Objekt ziel)
), bleibt es dem jewailigen Charakter überlassen, wie er den Angriff bewerkstelligt.