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.
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.
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.
Da Java keine Mehrfachvererbung unterstützt, könnten / sollten Sie
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 .
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.
Tags und Links java inheritance interface composition implementation