Wie tief darf eine Vererbungshierarchie sein?

Status
Nicht offen für weitere Antworten.

Marco13

Top Contributor
Hi

Mal eine allgemeine ... fast schon philosophische Frage: Wie tief darf (oder sollte) eine Vererbungshierarchie sein?

Tiefe Vererbungshierarchien sind vielleicht "theoretisch gut", in der Praxis können sie aber schwer wartbar oder schlicht unübersichtlich sein. Auf den Seiten, die man bei Websuchen diesbezüglich so findet (z.B. auf http://www.javaspecialists.eu/archive/Issue121.html ), steht im allgemeinen, dass eine Vererbungstiefe von ca. 5 noch OK ist, es aber in Richtung 10 schon kritisch wird. Grundsätzlich sehe ich die Problematik bei tiefen Hierarchien. Aber ich habe kaum Seiten gefunden, wo auf dieses Thema speziell in bezug auf Java Interfaces eingegangen wurde. Ich denke, dass da zwischen Interface-Hierarchien und Klassen-Hierarchien ein gewaltiger Unterschie ist, und diese "Grenzen" oder Aussagen bezüglich der maximalen Tiefe bei Interfaces praktisch nicht greifen.

Der Anlass für meine Frage: Im Moment bastle ich an einer Art Bibliothek, wo im Moment schon eine "Vererbungs"tiefe von ca. 11 bis 12 vorkommt. Allerdings sind die ersten 7-8 Stufen dieser Vererbung ausschließlich interfaces. Der Teil der Hierarchie, der tatsächlich aus Klassen besteht, ist im Moment die obligatorische Abstract->Default->Special-Kette
interface X
-> class AbstractX implements X
--> class DefaultX extends AbstractX
---> class SpecialX extends DefaultX

Die Bibliothek soll ziemlich allgemein werden. D.h. es soll praktisch die Möglichkeit geben, in jeder Stufe der Interface-Hierarchie eine konkrete Klasse einzuklinken. Die Frage ist, ob man sich diese Möglickeit teilweise verbauen sollte, indem man krampfhaft versucht, die Interface-Hierarchie plattzudrücken, oder ob ich Recht habe mit der Annahme, dass sich die "Daumenregeln" zur maximalen Tiefe der Vererbungshierarchie effektiv nur auf echte Klassen beziehen.

Bin schon gespannt auf eure Meinungen.
 
M

maki

Gast
Meine Meinung:
Das Problem mit tiefen Vererbungshierarchien betrifft hauptsächlich Klassenvererbung, da u.U. das Verhalten über mehrere Generationen hinweg verfolgt werden muss.

Ansonsten würde ich vielleicht (?) soviel wie möglich vom Defaultverhalten in die Abstrakte Klasse packen und die Spezialimplementierung parallel zur Defaultimplmentierung stellen, ungefähr so:

interface X
-> class AbstractX implements X
--> class DefaultX extends AbstractX
--> class SpecialX extends AbstractX

Nachtrag:
Ach ja, würde auch nicht allzuviel Vererben auch mit Interfaces, nur die wirklich notwendigen "zwischenschritte" der Interfaces angeben, verringert zwar die Flexibilität, aber erhöht die Übersicht.
Viele API bzw. Klassen/Interfacehierarchien werden falsch verwendet weil sie zu komplex sind, dann lieber "plattdrücken".
 

Ebenius

Top Contributor
7-8 Schritte für Interfaces finde ich im allgemeinen etwas viel. Sicher gibt's dafür Anwendungsfälle, aber meisten vererbe ich Interfaces höchstens mit Tiefe 3. Ausnahme gibt's hier manchmal in GUI-Modellen, da geht's auch mal ein bisschen weiter.

// Nachtrag: Du solltest hauptsächlichen aufpassen, dass die Anzahl der implementierten Schnittstellen einer Klasse nicht überhand nimmt. Irgendwie muss man als Nutzer einer Klasse möglichst innerhalb kurzer Zeit überblicken können was sie kann und was nicht. Wenn eine Klasse dann 20 Interfaces implementiert, ist man schnell mal überfordert.
 

FArt

Top Contributor
Wenn man eine Klasse viele Interfaces erfüllen lässt oder eine sehr große Vererbungshierarchie "benötigt", kann man meiner Meinung nach von einem Designfehler ausgehen.
 

Ebenius

Top Contributor
FArt hat gesagt.:
Wenn man eine Klasse viele Interfaces erfüllen lässt oder eine sehr große Vererbungshierarchie "benötigt", kann man meiner Meinung nach von einem Designfehler ausgehen.
Es sei denn man arbeitet mit Swing. :-D
 

tfa

Top Contributor
Ebenius hat gesagt.:
FArt hat gesagt.:
Wenn man eine Klasse viele Interfaces erfüllen lässt oder eine sehr große Vererbungshierarchie "benötigt", kann man meiner Meinung nach von einem Designfehler ausgehen.
Es sei denn man arbeitet mit Swing. :-D
Genau! Marco hat bestimmt mal wieder alles von JComponent abgeleitet :D
 

Marco13

Top Contributor
FArt hat gesagt.:
Wenn man eine Klasse viele Interfaces erfüllen lässt oder eine sehr große Vererbungshierarchie "benötigt", kann man meiner Meinung nach von einem Designfehler ausgehen.

Darum ging es ja. Nur bin ich nicht sicher, ob ein Designfehler nur bei einer großen Hierarchie von Klassen vorliegt, oder auch schon bei einer großen Hierarchie von Interfaces. Das ist ja schon was anderes...

Ich habe zwar die Erfahrung gemacht, dass "einfache Beispiele" dazu führen, dass man "einfache Lösungen" für das Beispiel aufgezeigt bekommt, die in der konkreten Anwendung dann nicht viel weiterhelfen, aber ich hoffe mal auf die wohlwollende Einsicht der Antwortenden, dass das ein STARK vereinfachtes, plakatives Beispiel ist (Aber vielleicht sind die "einfachen Lösungen" ja trotzdem inspirierend :) ) :

Code:
interface Lebewesen { void atme(); }
interface Tier extends Lebewesen { void esse(); }
interface Mensch extends Tier { void denke(); }
interface Programmierer extends Mesch { void programmiere(); }

Diese Interfaces sollen einen "Bibliotheks-Charakter" haben. D.h. es soll später Module geben, die sehr generisch sind, und mit beliebigen "Lebewesen" umgehen können. Und sie sollen diese auch NUR als solche kennen. Deswegen das Interface. Andere Module sollen mit "Tieren" umgehen können, und sie sollen sie AUCH NUR als solche kennen. Und so weiter. (Dazu kommen erschwerend ggf. evtl. noch einige "Mixin-Interfaces", die prinzipiell in jeder Stufe dazugenommen werden könnten, aber das ist fast schon ein anderes Thema).

Jede Stufe der Interface-Hierarchie hat also - vereinfacht gesagt - ihre Exsitenzberechtigung darin, dass ein Modul NUR die Methoden aus dieser Stufe kennen soll, und dass es potentiell konkrete Implementierungen gibt, die auch NUR die jeweilige Stufe implementieren.

FArt hat gesagt.:
Wenn man eine Klasse viele Interfaces erfüllen lässt...

Ich bin mir nicht sicher, wie du in diesem Fall "die Anzahl der Interfaces" definierst, die eine konkrete Klasse dann implementiert. Ein "DefaultProgrammierer" implementiert ja nur eigentlich nur EIN Interface, nämlich "Programmierer" (damit zwar auch alle anderen, aber das ist ja gewünscht - an der Stelle, wo man das Programmierer-Interface kennt, braucht es einen ja in vielerlei Hinsicht nicht unbedingt zu interessieren, dass das vielleicht die 10. Stufe einer Hierarchie von Interfaces ist)
 

Ice-Tea

Bekanntes Mitglied
Code:
interface Lebewesen { void atme(); }
interface Tier{ void esse(); }
interface Mensch{ void denke(); }
interface Programmierer{ void programmiere(); }



wie wäre es denn damit:

eine klasse kann alles und implementiert viele kleine interfaces.

Dann nur noch ein cast und schon kann ein Mensch nur noch atmen aber nichts mehr essen, denn es ist ja kein mensch mehr, sondern "nur noch" lebewesen. zumindest stehen nicht mehr methoden zur verfügung.

Ist gar nicht so lange her, da hab ich mir auch gedanken über eine Hierachische Inferfacestruktur gemacht. Ich fand jedoch diese art ist leichter und besser zu implementieren.

UND - das ganze hat einen Vorteil: Du kannst einem Schwein das programmieren beibringen :lol:
 

0x7F800000

Top Contributor
Ice-Tea hat gesagt.:
UND - das ganze hat einen Vorteil: Du kannst einem Schwein das programmieren beibringen
Ja, geil... Wenn du dir dann ein einfaches Schwein zur Herstellung von HotDogs erschaffst, fragt es dich dann erstmal nach einer fetten Villa, nem riesenauto und 20 Jahren zeit für ein Studium an der MIT.

dadurch gehen doch grad alle Vorteile verloren ???:L
 

Ice-Tea

Bekanntes Mitglied
Mein fehler...
Hast recht, die interfaces müssen schon erweitert werden.
Ohne Luft zum atmen lebt mein Schwein sonst nicht einmal lange genug um die große eines HotDogs zu erreichen.
 

Marco13

Top Contributor
Die Möglichkeit, eine Klasse alles implementieren zu lassen, fällt weg - aus dem Grund, den Andrey schon (etwas verschlüsselt :wink: ) genannt hat: Die Methoden der unteren Interfaces zu implementieren kann sehr aufwändig sein - und die Voraussetzungen dafür sind u.U. sehr komplex. Natürlich kann die Hierarchie der Klassen in gewisser Hinsicht "parallel" zu der der Interfaces verlaufen:
Code:
class AbstractLebewesen implements Lebeswesen { void atme() { System.out.println("Schnauf..."); }}
class AbstractTier extends AbstractLebewesen implements Tier
{ 
    // void atme() { System.out.println("Schnauf..."); }} // Muss nicht mehr implementiert werden: Schon in der abstrakten Klasse vorhanden....
    void esse() { System.out.println("Mampf..."); }
}
Aber das ändert ja nichts an der "zwingend"(?) vorgegebenen Tiefe der Interface-Hierarchie.

In gewisser Hinsicht gäbe es eine Lösung - die auch schon in der Collections-API von Sun verwendet wurde: Es gibt EIN Interface, wo ALLE Methoden drinstehen. Bei Methoden, die nicht unterstützt werden, wirft man eine "UnsupportedOperationException". Das halte ich aber nicht für sinnvoll - habe gerade mal einen Thread zu diesem Thema eröffnet: Zum Sinn von "UnsupportedOperationException" - weil das hiermit eigentlich nurnoch sehr indirekt zu tun hat.

Sowas würde mir jedenfalls nicht so gut gefallen:
Code:
class Schwein implements Mensch
{
    ...
    void denke() { throw new UnsupportedOperationException("Oink?"); }
}
:?


(BTW: Als Alternativen hatte ich schon an das IAdaptable (oder "Extension Object") Pattern gedacht, aber das passt nicht so gut (keine Comiliezeit-Sicherheit, und zu kompliziert zu verwenden, wenn die Interfaces "oft" abgefragt werden müssen (und nicht nur EINmal, wie z.B. bei einem Plugin))
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
L MVC - Wie viel darf mein Controller machen ? Softwareentwicklung 20
P Nutzung GPL-lizenzierter Bibliotheken: Was darf man? Softwareentwicklung 52
A Was ist RSync und wie darf ich es nutzen? Softwareentwicklung 11
M wie funktioniert eine KI mathematisch Softwareentwicklung 6
W Datenhaltung und Darstellung - Hat jemand eine Idee? Softwareentwicklung 41
S Welche Programmiersprache für eine 3D-Software? Softwareentwicklung 6
N Technologie Grundlagen für eine "App" Softwareentwicklung 12
T Gibt es eine Software die Texte für Skype automartisch (automassage) sendet ? Softwareentwicklung 4
J Suche noch eine Loesung fuer Kommunikation zwischen Webserver und ein Programm Softwareentwicklung 0
J Gibt es eine Algorithmus dafür??? Softwareentwicklung 5
U Individualsoftware - eine Gefahr für Kunden oder die günstigere Alternative? Softwareentwicklung 7
T Schützt die GPL auch eine implementierte Idee? Softwareentwicklung 5
A Gibt es eine Alternative zu SQL Strings im Prorammcode? Softwareentwicklung 41
I Grundlegende Anforderungen an eine Software Softwareentwicklung 14
O Wie funktioniert eigentlich eine Programmiersprache? Softwareentwicklung 10
D Ist das bereits eine Softwareentwicklung? Softwareentwicklung 3
M Eine Tabelle aus mehreren anderen Tabellen erzeugen! Softwareentwicklung 3
N gibt es eine RFC die speziell "bug tracking" besch Softwareentwicklung 5
Redfrettchen Lieber eine neue oder eine allgemeine Klasse? Softwareentwicklung 2
R Ein Thread für eine Methode Softwareentwicklung 2
1 Wie erstellt man so eine Website? Softwareentwicklung 14
M Eine Instanz übergeben ohne sie neu zu bilden Softwareentwicklung 21
T Klassendiagramm: Kann Attribut eine Liste enthalten? Softwareentwicklung 1
F Ist der Name eines Ojekts eine Eigenschaft Softwareentwicklung 7

Ähnliche Java Themen

Neue Themen


Oben