Wie kann eine untergeordnete Schnittstelle die Implementierungen ihrer Eltern wiederverwenden?

8

Kürzlich hatte ich ein Interview und mir wurde die folgende Frage gestellt. Gegeben die folgende Klassen- / Schnittstellenstruktur:

Frage:

Wie kann man die Schnittstelle EmployedStudent implementieren, um Code aus StudentImpl und EmployeeImpl wiederzuverwenden.

Ich habe vorgeschlagen, Mitarbeiter und Studenten in meine Implementierung zu integrieren.

Aufgrund der Reaktion des Interviewers glaube ich nicht, dass sie die beste Lösung gefunden haben. Ich habe viel darüber nachgedacht, aber ich kann mir keine andere Lösung ausdenken.

    
gstackoverflow 10.03.2015, 15:34
quelle

5 Antworten

5

Erstellen Sie eine Klasse, die sowohl Employee als auch Student implementiert. Erstellen Sie in Ihrer Klasse eine Instanz von EmployeeImpl und StudentImpl . Veranlassen Sie, dass Ihre Klasse alle Methodenaufrufe an eines der Objekte delegiert.

%Vor%     
user1438038 10.03.2015 15:45
quelle
3

Sie könnten also implements Employee, Student intern sowohl an EmployeeImpl als auch an StudentImpl delegieren, aber auch von einer Implementierungsklasse übernehmen.

Nun schlägt die Klasse name EmployeedStudent (nicht StudyingEmployee oder BothEmployeeAndStudent) vor:

%Vor%

Ja, ein bisschen effizienter, als nur an eine andere Klasse zu delegieren.

Der Anwendungsfall ist jedoch weit davon entfernt, realistisch zu sein: alle möglichen Kombinationen sind für mehrere Klassen denkbar. In diesem Fall ist Ihre Lösung universeller. Wirklich universell, ist ein Lookup-Mechanismus:

%Vor%

Das ist ein Lookup von Fähigkeiten . Es kann typischerweise eine schwerfällige Vererbungshierarchie, beispielsweise von Fahrzeug, RoadVehicle, SwimmingVehicle (Boot), FlyingVehicle (Flugzeug), WaterAirplane (?), AmphibianTank (?), Durch Nutzung der Fähigkeiten Schwimmen, Fliegen, Fahren ersetzen.

Der Unterschied ist die gesamte Entkopplung.

    
Joop Eggen 10.03.2015 16:19
quelle
1

Da Java keine Mehrfachvererbung unterstützt, könnten / sollten Sie

  • hat entweder ein Feld für jede der gewünschten Superklassen
  • oder herleiten von einer Oberklasse und haben ein Feld für die andere.

Die Felder werden dann durch "unsere" Implementierung der jeweiligen Methoden bezeichnet.

Dies ist eines der Entwurfsmuster aus dem GoF , ich denke, es ist das Proxy-Muster .

    
glglgl 10.03.2015 15:38
quelle
1

Mit Java 8 können Sie Code in die Schnittstelle selbst verschieben. Das löst das Problem der "Mehrfachvererbung".

    
Necreaux 10.03.2015 15:46
quelle
1

Obwohl das Prinzip der Schnittstellentrennung manchmal hilfreich sein kann und manche Leute über die Idee von Schnittstellen spotten, die nicht versprechen, dass alle Implementierungen alle Mitglieder unterstützen, würde ich vorschlagen, dass es hilfreich ist, Student und% zu haben. co_de% interfaces, die Employee und isStudent members enthalten und dann isEmployee beide Schnittstellen implementieren; Einige Methoden wie Person sollten nicht für jemanden funktionieren, der kein Angestellter ist, aber andere wie giveRaise() sollten gut funktionieren (wenn jemand kein Geld verdient hat, sollte die Methode einfach null zurückgeben).

>

Es mag zwar hässlich erscheinen, alle getOutstandingPay() -Objekte mit Methoden zu komplizieren, die für viele von ihnen nicht anwendbar sind. Ein solches Design vermeidet jedoch Schwierigkeiten, falls ein Student eingestellt wird oder ein Mitarbeiter beginnt, Klassen zu belegen. Getrennte Klassen für Person , Student und Employee erfordern, auch wenn dies leicht möglich wäre, dass ein StudentEmployee , der einen Job erhalten hat, durch eine neue Objektinstanz ersetzt wird um ein Student zu werden. Im Gegensatz dazu kann man, wenn man eine StudentEmployee -Klasse hat, deren Instanzen mit Methoden wie Person umgehen können oder auch nicht, mit Situationen umgehen, in denen sich die Fähigkeiten von Objekten während ihrer Lebensdauer ändern.

    
supercat 10.03.2015 15:52
quelle