Frage

Ich begann mit einer generischen Schnittstelle aus aufgerufen ILogin. Die Schnittstellen erfordert, dass Sie zwei Eigenschaften implementieren: Benutzer-ID und Passwort. Ich habe viele Login-Typ-Klassen, die diese Schnittstelle implementieren. Da mein Projekt wuchs und wuchs, fand ich, dass viele Klassen den Benutzer-ID und Passwort Code wiederholt. Jetzt entscheide ich, dass ich eine Basis Login-Klasse benötigen.

Ist es richtig, eine abstrakte Basis Login-Klasse zu erstellen, die die ILogin-Schnittstelle implementiert und haben alle meine konkreten Klassen nur von der abstrakten Klasse erben und überschreiben, wenn nötig? Ursprünglich dachte ich es würde mit diesem kein Problem sein. Dann begann ich denke, dass ILogin wahrscheinlich nicht mehr benötigt, weil es wird wahrscheinlich immer nur von meiner abstrakten Klasse implementiert werden.

Sie haben einen Vorteil sowohl die abstrakte Klasse und die Schnittstelle herum zu halten?

Danke!

War es hilfreich?

Lösung

Auf jeden Fall. Denken wir an einem konkreten Beispiel.

Sagen wir eine abstrakte Klasse Animal haben. Sprich, wir machen einige Unterklassen Cat, Dog, Mosquito und Eagle. Wir können implementieren seine Eat(), Breathe(), Sleep() Methoden der abstrakten Klasse Animal.

So weit, so gut. Nun lassen Sie uns sagen, dass wir die Fly() Methode für die Mosquito und Eagle Klassen haben wollen. Da diese beiden Organismen nicht wirklich gut verwandt sind (ein Vogel ist, ist eine andere ein Insekt) wäre es nicht einfach, mit einem gemeinsamen Vorfahren kommen für die beiden, die wir als abstrakte Klasse haben kann. Dies würde am besten durch eine Schnittstelle IFly umgesetzt werden.

Die IFly-Schnittstelle kann ein Fly() Verfahren müssen umgesetzt werden. Beide Mosquito und Eagle Klassen können beide Unterklassen der abstrakten Klasse Animal sein und die Schnittstelle IFly implementieren und in der Lage sein Eat(), Breathe(), Sleep() und Fly() ohne irgendeine Art von ungerade ancenstral Beziehung zwischen den beiden Klassen zu haben.

Andere Tipps

ich in der Regel Code gegen abstrakte Klassen, wenn es Sinn macht und implementieren (und in einer externen Verträgen Montag / Bibliothek erstellen) eine Schnittstelle in jeder Klasse (abstract oder nicht), so kann ich leichte Windows Communication Foundation oder Inversion of Control wenn nötig (die spöttischen fast immer). Dies hat für mich zur zweiten Natur geworden.

Auf jeden Fall. Die Schnittstelle ist immer der richtige Weg zu gehen -. Auf diese Weise alles, was es umsetzen kann (einschließlich etwas, das bereits einen Elternteil hat)

Die abstrakte Klasse neigt es zu machen, so dass Sie einige Stücke dieser Funktionalität nicht neu implementieren müssen. Swing verwendet es ein wenig, werden sie eine Schnittstelle haben und dann eine Standardimplementierung für Sie nur eine der fünf Methoden außer Kraft zu setzen oder es könnte für Sie kümmern Hörer des Hinzufügens, aber Sie haben nicht, dass die Basisklasse zu verwenden, wenn Sie nicht wollen.

Wenn Sie Ihre abstrakte Klasse ist die nur Klasse, die die Schnittstelle jemals umsetzen wird, dann können Sie immer überprüfen, nur für Instanzen der abstrakten Klasse, die Sie nicht die Schnittstelle benötigen. Aber wenn Sie wollen mit neuen Klassen zukunftskompatibel sein noch nicht geschrieben, die die abstrakte Klasse nicht erweitern, sondern die Schnittstelle verwenden könnte, dann halten Sie die Schnittstelle jetzt verwendet wird.

Ich bin mit cfeduke. Ich beginne immer mit den Schnittstellen und in der Vergangenheit haben abstrakte Klassen verwendet, die Schnittstellen implementieren und bieten grundlegende Funktionalität Wiederverwendung von Code unter den Klassen zu fördern, die von der abstrakten Klasse erben. Mocking und IOC sind im Allgemeinen Schnittstelle abhängig, allein aus diesem Grunde würde ich Schnittstellen in meinem Design verwenden.

Wenn die abstrakte Klasse Funktionalität hat, ist es ratsam, es zu halten. Aber wenn es enthält nur abstrakte Methoden und keine Felder. Ich sehe keinen Gebrauch beide zu halten.

Edit: Ich arbeite auf Legacy-Code mit vielen abstrakten Klassen. Wenn ich jemals die Zeit habe, werde ich die Schnittstellen hinzuzufügen (und möglicherweise die leeren Abstracts entfernen). Denn mit Schnittstellen arbeiten stark verbessert die Möglichkeiten. Und sie ehren ihre Namen durch genau die Schnittstelle zu definieren.

Ihre Schnittstelle definiert den Vertrag, der für das Objekt erfüllt sein müssen in Kauf genommen werden; Ihre abstrakte Klasse definiert den Auftrag, die erfüllt werden müssen, und legt einige spezifische Implementierungsdetails.

Denken auf diese Weise davon; wenn Sie es jemals für möglich halten für jedermann zu wollen, diesen Vertrag auf eine andere Weise als die Art und Weise zu erfüllen, dass die abstrakte Klasse skizziert (zum Beispiel mit einer anderen Träger Datentyp-Implementierung), dann sollten Sie beide haben die Schnittstelle und die abstrakte Klasse, die dass implementiert.

Es gibt fast keinen Overhead beteiligt, die sowohl die abstrakte Klasse und die Schnittstelle; Ihr Risiko mit diesem Ansatz beinhaltet in erster Linie eine spätere Coder über die Schnittstelle kommen zu realisieren, nicht, dass es eine abstrakte Klasse ist, die die Schnittstelle implementiert, und eine gesamte Implementierung von Grund auf neu erstellen, wo es muss nicht sein. Ich würde sagen, dass dies um durch die Angabe in Ihrer Interface-Dokumentation erhalten werden könnte, dass es eine „default“ Implementierung der Schnittstelle in der abstrakten Klasse; während einige Coding-Standards auf diese Praxis Stirnrunzeln kann, sehe ich keine wirklichen Probleme.

Ich würde immer empfehlen, dass Sie Schnittstellen verwenden. Abstrakte Klassen haben den Vorteil, dass Sie in Standard-Funktionalität hinzufügen können, aber erfordern, dass ein Benutzer ihre einzige Vererbung ist ziemlich aggressiv.

Microsoft-Klassenbibliotheken bevorzugen abstrakte Klassen über Schnittstellen in einer Reihe von Fällen, weil es ihnen ermöglicht, die zugrunde liegende Klasse zu ändern. Hinzufügen einer Methode zu einer abstrakten Klasse bricht selten jemand, der von ihr erbt. Hinzufügen einer Methode zu einer Schnittstelle bricht immer seine Implementierer. Doch dies stellt eine der besten Gründe für Schnittstellen. Die schreckliche Möglichkeit, dass Microsoft bereits verwendet haben, kann Ihr ein Erbe bis

Ich würde vorschlagen, Sie jedoch, dass in Ihrem speziellen Fall können Sie möchten das Design-Muster Sie verwenden zu überdenken. Es scheint ungewöhnlich viele „Anmeldetyp“ Klassen zu haben.

ich denke, einen Vorteil, dass die Schnittstelle hält die Fähigkeit für zukünftige Klassen wäre, um mehrere Schnittstellen zu implementieren, während eine Klasse nur von einer abstrakten Klasse erben kann.

Sie können die Funktionalität von Unterklassen erweitern, indem eine neue Schnittstelle mit einem anderen Satz von Methoden zu schaffen.

Angenommen, Sie fragen, speziell, wenn die Schnittstelle und die abstrakte Klasse identische Signaturen haben ...

... (Wenn die Mitglieder der Schnittstelle unterschiedlich sind in keiner Weise von den Mitgliedern der abstrakten Klasse dann natürlich die Antwort ja ist, kann es eine Notwendigkeit für beide sein)

... aber vorausgesetzt, die Mitglieder sind identisch, dann ist der einzige Grund, warum ich denken kann müssen beide sind, wenn Sie in einem System sind Codierung, die nicht mehrere Implementierungsvererbung erlaubt es zwei Klassen in Ihrem System, das muß sein polymorph ähnlich, sondern müssen von verschiedenen Basisklassen erben ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top