Mehrfaches Vererbungsdesign in Java

8

Wie gehst du damit um, nur eine Vererbung in Java zu haben? Hier ist mein spezifisches Problem:

Ich habe drei (vereinfachte) Klassen:

%Vor%

Dies ist, was ich als meine grundlegendste Implementierung betrachte, aber ich möchte andere Implementierungen machen.

Sagen wir, dass ich eine neue Variable say wordLength hinzufügen möchte, aber ich möchte es mit Vererbung hinzufügen. Bedeutung Ich möchte diese ursprüngliche AbstractWord-Klasse nicht ändern. Ie etwas in der Richtung von diesem:

%Vor%

Ich weiß, dass Java mich das nicht machen lässt, aber es hat meinen Code sehr hässlich gemacht. Gerade jetzt, wenn ich ein Feld hinzufüge, füge ich es nur zu AbstractWord hinzu, aber dann muss ich entweder das AbstractWord (und Word und WordDescriptor) umbenennen. (Ich kann das Feld nicht einfach wegen der Abwärtskompatibilität zu dem anderen hinzufügen, es bricht gleich Methoden und ähnliches).

Das scheint ein ziemlich häufiges Designproblem zu sein, aber ich habe mir den Kopf zerbrochen und ich kann mir keine schönen Lösungen einfallen lassen.

Gibt es ein Entwurfsmuster, das dies anspricht? Ich habe einige mögliche Lösungen, aber ich wollte sehen, ob es etwas gab, das mir fehlte.

danke, Jake

Update: Länge bezieht sich auf die Anzahl der Silben im Wort (Entschuldigung wegen mangelnder Klarheit)

    
sixtyfootersdude 26.01.2010, 22:37
quelle

7 Antworten

9

Komposition über Vererbung favorisieren.

Lösung berücksichtigt, dass möglicherweise ein anderer Worttyp WordLengthSupport benötigt.

Ähnlich können andere Schnittstellen erstellt und implementiert werden, und verschiedene Wortarten können diese Schnittstellen mischen und abgleichen.

.

%Vor%

.

%Vor%

.

%Vor%

.

%Vor%

.

Das Strategie-Pattern definiert eine Familie von Algorithmen, kapselt sie ein und macht sie austauschbar. Strategie lässt den Algorithmus unabhängig von Clients variieren, die ihn verwenden.

Diese Lösung verwendet kein Strategie-Muster, kann aber für dasselbe umstrukturiert werden.

    
Gladwin B 27.01.2010, 00:07
quelle
3

Verwenden Sie einfach Komposition statt Vererbung:

a BetterWord ist-ein AbstractWord das hat-a Length :

%Vor%

BEARBEITEN

Wenn die API ein Objekt vom Typ Length benötigt, fügen Sie einfach einen Getter hinzu:

%Vor%

Oder benennen Sie die Implementierung Length in LengthImpl um und definieren Sie eine Schnittstelle Length , da eine Klasse mehrere Schnittstellen implementieren kann.

    
Andreas_D 26.01.2010 22:57
quelle
2

In Ihrem speziellen Beispiel könnten Sie das Decorator -Muster in Verbindung mit Schnittstellen verwenden, um Ihre Word -Klasse mit zusätzlichen zu ergänzen Funktionalität; z.B.

%Vor%

Außerdem ist es bemerkenswert, dass das Fehlen einer Mehrfachvererbung in Java nicht wirklich das Problem ist; es ist mehr ein Fall von Überarbeitung Ihres Designs. Im Allgemeinen wird es als schlechte Praxis angesehen, die Vererbung zu überschreiben, da tiefe Vererbungshierarchien schwer zu interpretieren sind.

    
Adamski 26.01.2010 22:42
quelle
2

Wenn ich es ansehe, ist mein erstes Gefühl, dass Ihr Modell ein bisschen kompliziert ist.

Ein Wort hat eine Zeichenfolge, um das Wort selbst zu beschreiben, das zusammen mit einer Klasse in dem Wortobjekt gespeichert wird, um zu sagen, dass es ein Substantiv, Verb, Adjektiv usw. ist. Eine andere Eigenschaft eines Worts ist die Länge der im Wort gespeicherten Zeichenkette Objekt.

Denken Sie an Dinge in Bezug auf "ist-a" und "hat-eine" Beziehungen und Sie können eine Menge Komplexität entfernen.

Warum brauchen Sie zum Beispiel einen WordDescriptor, der AbstractWord erweitert? Wird sich ein Wort von einem Verb zu einem Adjektiv ändern? Ich hätte gedacht, dass der Worttyp beim Erstellen des Objekts festgelegt wurde und sich während der Lebensdauer des Word-Objekts nicht ändern würde. Sobald Sie ein Word-Objekt für das Wort "Australien" hatten, änderte sich die Art des Wortes für die Lebensdauer des Objekts nicht.

Hmmm. Vielleicht haben Sie ein Word-Objekt, das das Wort "bellen" darstellt, nachdem Sie das Objekt mit einer Art "Verb" versehen haben, um den Klang eines Hundes zu beschreiben. Dann erkennen Sie, dass Sie tatsächlich das Wort-Objekt benötigen, um ein Substantiv zu repräsentieren, das die Bedeckung eines Baumes beschreibt. Möglich, aber sowohl die Rinde des Hundes als auch die Rinde des Baumes können existieren.

Ich denke also, dass das Modell, das Sie gewählt haben, ein bisschen zu kompliziert ist und dass Ihre Frage gelöst werden kann, indem Sie Ihr ursprüngliches Objektmodell vereinfachen und vereinfachen.

Stellen Sie sich zunächst eine Frage zu jedem der Vererbungsaspekte Ihres Basismodells.

  

Wenn ich sage, Klasse B erweitert Klasse A, kann ich sagen, dass Klasse B "ist-a" Klasse A ist und dass ich ihr Verhalten spezialisiere?

Beispielsweise kann eine Basisklasse Animal erweitert werden, um die spezialisierte Klasse von Kangaroo zu bieten. Dann kannst du sagen, dass "das Känguru" ein "Tier" ist. Du spezialisierst das Verhalten.

Sieh dir dann die Attribute an. Ein Kangaroo hat ein Location-Attribut, um zu beschreiben, wo es gefunden wird. Dann können Sie sagen, ein Känguru "hat-a" Standort. Ein Kangaroo "is-a" Standort macht keinen Sinn.

Ähnlich hat ein Wort "hat-eine" Länge. Und die Aussage eines Wortes "ist-a" Länge ergibt einfach keinen Sinn.

BTW Alle australischen Referenzen in diesem Beitrag sind beabsichtigt, Australien Day zu feiern, der heute 26. Januar ist!

HTH

    
Rob Wells 26.01.2010 23:10
quelle
0
  

(Ich kann das Feld nicht einfach aus Gründen der Abwärtskompatibilität zum anderen hinzufügen, es ist gleichbedeutend mit Methoden und dergleichen).

Es wird die Quellenkompatibilität nicht beeinträchtigen. Es sei denn, du machst etwas wirklich Verrücktes in deinen Gleichen Methoden.

Und das Umbenennen Ihrer Klassen ist im Allgemeinen nicht die Art, die Binärkompatibilität zu handhaben.

    
Anon. 26.01.2010 22:42
quelle
0

Das Problem ist nicht, wie man mit einer einzelnen Vererbung umgeht. Was Sie vermissen, ist nicht wirklich ein Entwurfsmuster, sondern lernen, die API getrennt von der Implementierung zu entwerfen.

Ich würde es so implementieren:

%Vor%

Wenn Sie bei dieser grundlegenden Konfiguration eine Eigenschaft length angeben möchten, müssen Sie nur Folgendes tun:

%Vor%

Die anderen Antworten, die die Zusammensetzung der Eigenschaften sowie das Decorator-Muster verwenden, sind ebenfalls vollkommen gültige Lösungen für Ihr Problem. Sie müssen nur herausfinden, was Ihre Objekte sind und wie "zusammensetzbar" sie sind und wie sie verwendet werden sollen - daher sollten Sie zuerst die API entwerfen.

    
aberrant80 27.01.2010 03:11
quelle
0

/ **  * Erstes Beispiel  * /

%Vor%

/ **

  • Wow, dieses Monster wurde größer

  • Stellen Sie sich vor, dass Sie 4 lvl der Vererbung brauchen

  • es würde so viel Zeit brauchen, um diese Hölle zu schreiben

  • Ich spreche gar nicht davon, dass der Benutzer von iface denkt

  • Welche Felder brauche ich fieldsA fieldsB fieldsC oder ein anderes

So funktioniert die Komposition hier nicht und deine erbärmlichen Versuche sind nutzlos

Wenn Sie an Oject Oriented Programmierung denken

Sie brauchen BIG-Modelle mit 6-7 lvls mehrfacher Vererbung

weil das ein guter Test ist und weil er Modellen des realen Lebens oder mathematischen Modellen entspricht, die viertausend Jahre lang von der Zivilisation getestet wurden.

Wenn Ihre Modelle 2 lvl der Vererbung benötigen, hören Sie auf, mit OO

zu spielen

U kann es leicht mit jeder Sprache implementieren, sogar prozeduralen wie C oder Basic Sprache  * /

    
Dss D 04.09.2015 09:58
quelle