840 Stimmen

Schnittstelle vs. Basisklasse

Wann sollte ich eine Schnittstelle und wann eine Basisklasse verwenden?

Sollte es immer eine Schnittstelle sein, wenn ich keine Basisimplementierung der Methoden definieren möchte?

Wenn ich eine Hunde- und Katzenklasse habe. Warum sollte ich IPet anstelle von PetBase implementieren wollen? Ich kann verstehen, mit Schnittstellen für ISheds oder IBarks (IMakesNoise?), weil diese auf ein Haustier von Haustier Basis platziert werden können, aber ich verstehe nicht, welche für eine allgemeine Pet verwenden.

11 Stimmen

Nur ein Punkt, den Sie meiner Meinung nach berücksichtigen sollten - Schnittstellen können verschiedene Einschränkungen mit sich bringen, derer Sie sich möglicherweise erst in sehr späten Phasen bewusst sind. Zum Beispiel mit .NET können Sie nicht serialisieren eine Schnittstelle Mitglied Variable, so dass, wenn Sie eine Klasse Zoo und ein Mitglied Variable Array von IAnimals haben Sie nicht in der Lage, Zoo serialisieren (und das bedeutet, schreiben WebServices oder andere Dinge, die eine Serialisierung wäre ein Schmerz).

2 Stimmen

Diese Frage könnte helfen, das Konzept der Schnittstellen zu verstehen. stackoverflow.com/q/8531292/1055241

0 Stimmen

Ich bin nur neugierig. Ich traf in der CLR über C# den folgenden Auszug: I tend to prefer using the interface technique over the base type technique because the base type technique doesn’t allow the developer to choose the base type that works best in a particular situation. . Ich kann nicht begreifen, was in dem Auszug gemeint ist. Wir können einige Basistypen erstellen und für jeden von ihnen einen abgeleiteten Typ erstellen, so dass ein Entwickler einen Basistyp auswählen kann. Könnte mir bitte jemand erklären, was ich übersehe? Ich glaube, es kann ein Teil dieser Frage sein. Oder sollte ich eine andere Frage zu dem spezifischen Auszug stellen?

6voto

YeahStu Punkte 3980

Die Vorteile von Basisklassen gegenüber Schnittstellen wurden in den Submain .NET Coding Guidelines gut erläutert:

Basisklassen vs. Interfaces Ein Schnittstellentyp ist ein Teil Beschreibung eines Wertes, der potenziell von vielen Objekttypen unterstützt wird. Verwenden Sie Basisklassen anstelle von Schnittstellen wann immer möglich. Aus Sicht der Versionierung Perspektive sind Klassen flexibler als Schnittstellen. Mit einer Klasse können Sie Version 1.0 ausliefern und dann in Version 2.0 eine neue Methode zu der Klasse hinzufügen. Solange die Methode nicht abstrakt ist, alle bestehenden abgeleiteten Klassen weiter unverändert funktionieren.

Da Schnittstellen keine Unterstützung für Implementierungsvererbung unterstützen, ist das Muster, das für Klassen gilt, nicht gilt nicht für Schnittstellen. Das Hinzufügen einer Methode zu einer Schnittstelle ist gleichbedeutend mit dem Hinzufügen einer abstrakten Methode zu einer Basisklasse Klasse; jede Klasse, die das Schnittstelle implementiert, bricht zusammen, weil die Klasse die neue Methode nicht implementiert. Interfaces sind geeignet in der folgenden Situationen:

  1. Mehrere nicht miteinander verbundene Klassen wollen das Protokoll unterstützen.
  2. Diese Klassen haben bereits etablierte Basisklassen (zum Beispiel Beispiel, einige sind Bedienelemente für die Benutzeroberfläche (UI), und einige sind XML-Webdienste).
  3. Eine Zusammenlegung ist weder angemessen noch durchführbar. In allen anderen Situationen, ist die Klassenvererbung ein besseres Modell.

0 Stimmen

Ich finde, diese Antwort sollte mehr Aufmerksamkeit erhalten. Sie geht vielen Antworten hier gegen den Strich. Ich würde nicht sagen, dass ich vollständig zustimme, aber es gibt hier gute Argumente.

5voto

Joel Coehoorn Punkte 377088

Ein wichtiger Unterschied ist, dass Sie nur vererben können Basisklasse, aber Sie können die viele Schnittstellen. Sie sollten also nur dann eine Basisklasse verwenden, wenn Sie absolut sicher dass Sie nicht auch noch eine andere Basisklasse erben müssen. Wenn Sie außerdem feststellen, dass Ihre Schnittstelle zu umfangreich wird, sollten Sie versuchen, sie in einige logische Teile aufzuteilen, die unabhängige Funktionen definieren, da es keine Regel gibt, die besagt, dass Ihre Klasse nicht alle implementieren kann (oder dass Sie eine andere Schnittstelle definieren können, die sie einfach erbt, um sie zu gruppieren).

4voto

Als ich anfing, mich mit objektorientierter Programmierung zu beschäftigen, machte ich den einfachen und wahrscheinlich weit verbreiteten Fehler, die Vererbung zu nutzen, um gemeinsames Verhalten zu teilen - auch wenn dieses Verhalten für die Natur des Objekts nicht wesentlich war.

Um ein in dieser Frage häufig verwendetes Beispiel weiter auszuführen, gibt es Lose von Dingen, die man streicheln kann - Freundinnen, Autos, kuschelige Decken... - Ich könnte also eine Petable-Klasse haben, die dieses allgemeine Verhalten bietet, und verschiedene Klassen, die davon erben.

Es liegt jedoch nicht in der Natur eines dieser Objekte, petable zu sein. Es gibt weitaus wichtigere Konzepte, die son Die Freundin ist eine Person, das Auto ist ein Landfahrzeug, die Katze ist ein Säugetier...

Verhaltensweisen sollten zunächst Schnittstellen zugeordnet werden (einschließlich der Standardschnittstelle der Klasse) und nur dann zu einer Basisklasse befördert werden, wenn sie (a) einer großen Gruppe von Klassen gemeinsam sind, die Untermengen einer größeren Klasse sind - in demselben Sinne, dass "Katze" und "Mensch" Untermengen von "Säugetier" sind.

Der Haken an der Sache ist, dass Sie, nachdem Sie das objektorientierte Design besser verstanden haben, als ich es anfangs tat, dies normalerweise automatisch tun, ohne darüber nachzudenken. So wird die nackte Wahrheit der Aussage "Code an eine Schnittstelle, nicht an eine abstrakte Klasse" so offensichtlich, dass man kaum glauben kann, dass sich jemand die Mühe macht, dies zu sagen - und man versucht, andere Bedeutungen hineinzulesen.

Eine weitere Sache, die ich hinzufügen würde, ist, dass, wenn eine Klasse rein abstrakt - ohne nicht-abstrakte, nicht-vererbte Mitglieder oder Methoden, die dem Kind, dem Elternteil oder dem Kunden zugänglich sind - warum ist sie dann eine Klasse? Sie könnte in einigen Fällen durch eine Schnittstelle und in anderen Fällen durch Null ersetzt werden.

0 Stimmen

Eine rein abstrakte Klasse kann Standardverhaltensweisen für Methoden bereitstellen. Dies ist nützlich, wenn Ihre konkreten Klassen alle gemeinsame Methoden haben, die immer wieder neu zu implementieren überflüssig wäre.

0 Stimmen

stackoverflow.com/a/65939/2361131 spricht den gleichen Ton & eine andere Antwort hier stackoverflow.com/a/65939/2361131 fügt die Nuance der Wissensdarstellung hinzu

4voto

Jaimin Patel Punkte 4271

Schnittstellen gegenüber abstrakten Klassen bevorzugen

Begründung, die wichtigsten zu berücksichtigenden Punkte [zwei wurden hier bereits genannt] sind :

  • Schnittstellen sind flexibler, denn eine Klasse kann mehrere Schnittstellen implementieren kann. Da es in Java keine Mehrfachvererbung gibt, ist die Verwendung von abstrakte Klassen verhindern, dass Ihre Benutzer eine andere Klassenhierarchie Hierarchie. Im Allgemeinen sollten Sie Schnittstellen bevorzugen, wenn es keine Standard Implementierungen oder Zustände gibt. Java-Sammlungen bieten gute Beispiele für (Map, Set, etc.).
  • Abstrakte Klassen haben den Vorteil, dass sie eine bessere Vorwärts Kompatibilität. Sobald Kunden eine Schnittstelle verwenden, können Sie sie nicht mehr ändern; Wenn sie eine abstrakte Klasse verwenden, können Sie weiterhin Verhalten hinzufügen, ohne bestehenden Code zu ändern. Wenn die Kompatibilität ein Problem darstellt, sollten Sie die Verwendung von abstrakte Klassen.
  • Selbst wenn Sie Standardimplementierungen oder einen internen Status haben, erwägen, eine Schnittstelle und eine abstrakte Implementierung dieser Schnittstelle anzubieten . Dies wird den Kunden helfen, ihnen aber auch mehr Freiheit lassen, wenn sie wünschen [1].
    Natürlich wurde das Thema bereits ausführlich diskutiert an anderer Stelle diskutiert [2,3].

[1] Es fügt natürlich mehr Code hinzu, aber wenn die Kürze Ihr Hauptanliegen ist, hätten Sie Java wahrscheinlich von vornherein vermeiden sollen!

[2] Joshua Bloch, Effektives Java, Punkte 16-18.

[3] http://www.codeproject.com/KB/ar ...

3voto

Scott Lawrence Punkte 6695

Frühere Kommentare über die Verwendung von abstrakten Klassen für die gemeinsame Umsetzung ist definitiv auf der Marke. Ein Vorteil, der noch nicht erwähnt wurde, ist die Tatsache, dass die Verwendung von Schnittstellen die Implementierung von Mock-Objekten zum Zweck von Unit-Tests wesentlich erleichtert. Wenn man IPet und PetBase so definiert, wie Jason Cohen es beschrieben hat, kann man verschiedene Datenbedingungen einfach simulieren, ohne den Overhead einer physischen Datenbank (bis man sich entscheidet, dass es an der Zeit ist, die echte Sache zu testen).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X