Ich hatte kürzlich zwei Telefoninterviews, in denen ich nach den Unterschieden zwischen einer Interface- und einer Abstract-Klasse gefragt wurde. Ich habe jeden Aspekt von ihnen erklärt, an den ich denken könnte, aber es scheint, dass sie darauf warten, dass ich etwas Bestimmtes erwähne, und ich weiß nicht, was es ist.
Aus meiner Erfahrung denke ich, dass das Folgende wahr ist. Wenn mir ein wichtiger Punkt fehlt, lassen Sie es mich bitte wissen.
Schnittstelle:
Jede einzelne in einer Schnittstelle deklarierte Methode muss in der Unterklasse implementiert werden. In einer Schnittstelle können nur Ereignisse, Delegaten, Eigenschaften (C #) und Methoden vorhanden sein. Eine Klasse kann mehrere Schnittstellen implementieren.
Abstrakte Klasse:
Nur abstrakte Methoden müssen von der Unterklasse implementiert werden. Eine abstrakte Klasse kann normale Methoden mit Implementierungen haben. Abstrakte Klassen können neben Ereignissen, Delegaten, Eigenschaften und Methoden auch Klassenvariablen enthalten. Eine Klasse kann nur eine abstrakte Klasse implementieren, da in C # keine Mehrfachvererbung vorhanden ist.
Nach all dem stellte der Interviewer die Frage: "Was wäre, wenn Sie eine abstrakte Klasse mit nur abstrakten Methoden hätten? Wie würde sich das von einer Schnittstelle unterscheiden?" Ich wusste die Antwort nicht, aber ich denke, es ist das Erbe, wie oben erwähnt, oder?
Ein anderer Interviewer fragte mich, was wäre, wenn Sie eine öffentliche Variable in der Benutzeroberfläche hätten, wie würde sich das von der abstrakten Klasse unterscheiden? Ich habe darauf bestanden, dass Sie keine öffentliche Variable in einer Schnittstelle haben können. Ich wusste nicht, was er hören wollte, aber er war auch nicht zufrieden.
Siehe auch :
quelle
I insisted you can't have a public variable inside an interface.
Ich denke, Schnittstelle kann öffentliche Variable haben. Tatsächlich sind Variablen in der Schnittstelle automatisch öffentlich und endgültig.Antworten:
Während Ihre Frage angibt, dass es sich um "allgemeines OO" handelt, scheint sie sich wirklich auf die Verwendung dieser Begriffe in .NET zu konzentrieren.
In .NET (ähnlich für Java):
Als allgemeine OO-Begriffe sind die Unterschiede nicht unbedingt genau definiert. Beispielsweise gibt es C ++ - Programmierer, die möglicherweise ähnliche starre Definitionen haben (Schnittstellen sind eine strikte Teilmenge abstrakter Klassen, die keine Implementierung enthalten können), während einige sagen, dass eine abstrakte Klasse mit einigen Standardimplementierungen immer noch eine Schnittstelle oder eine nicht abstrakte ist Klasse kann weiterhin eine Schnittstelle definieren.
In der Tat gibt es eine C ++ - Redewendung namens Non-Virtual Interface (NVI), bei der die öffentlichen Methoden nicht virtuelle Methoden sind, die sich auf private virtuelle Methoden beziehen:
quelle
Wie wäre es mit einer Analogie: Als ich in der Luftwaffe war, ging ich zur Pilotenausbildung und wurde Pilot der USAF (US Air Force). Zu diesem Zeitpunkt war ich nicht zum Fliegen qualifiziert und musste an einem Flugzeugtypentraining teilnehmen. Nach meiner Qualifikation war ich Pilot (Abstract-Klasse) und C-141-Pilot (Betonklasse). Bei einem meiner Aufträge erhielt ich eine zusätzliche Aufgabe: Sicherheitsbeauftragter. Jetzt war ich noch Pilot und C-141-Pilot, aber ich habe auch Aufgaben als Sicherheitsbeauftragter wahrgenommen (ich habe sozusagen ISafetyOfficer implementiert). Ein Pilot musste kein Sicherheitsbeauftragter sein, andere Leute hätten es auch tun können.
Alle USAF-Piloten müssen bestimmte luftwaffenweite Vorschriften befolgen, und alle C-141- (oder F-16- oder T-38-) Piloten sind USAF-Piloten. Jeder kann Sicherheitsbeauftragter sein. Um es zusammenzufassen:
Hinweis hinzugefügt: Dies sollte eine Analogie zur Erläuterung des Konzepts sein, keine Kodierungsempfehlung. Siehe die verschiedenen Kommentare unten, die Diskussion ist interessant.
quelle
Jay
nicht mehr von mehreren Klassen (C-141-Pilot, F-16-Pilot und T-38-Pilot) erben kann. Bedeutet das, dass deren Klassen zu Schnittstellen werden sollten? Vielen DankIch denke, die Antwort, nach der sie suchen, ist der grundlegende oder OPPS-philosophische Unterschied.
Die Vererbung abstrakter Klassen wird verwendet, wenn die abgeleitete Klasse die Kerneigenschaften und das Verhalten der abstrakten Klasse gemeinsam nutzt. Die Art von Verhalten, die die Klasse tatsächlich definiert.
Andererseits wird die Schnittstellenvererbung verwendet, wenn die Klassen das periphere Verhalten gemeinsam haben, das die abgeleitete Klasse nicht unbedingt definiert.
Zum Beispiel. Ein Auto und ein LKW teilen viele Kerneigenschaften und das Verhalten einer abstrakten Klasse für Automobile, aber sie teilen auch ein peripheres Verhalten wie Abgas erzeugen, das selbst Nicht-Auto-Klassen wie Bohrer oder PowerGeneratoren gemeinsam haben und nicht unbedingt ein Auto oder einen LKW definieren So können Auto, LKW, Bohrer und PowerGenerator alle dieselbe Schnittstelle IExhaust gemeinsam nutzen.
quelle
accelerate
es Teil des Kernverhaltens der abstrakten Klasse von Automobile ist, kann ich nicht sagenaccelerate
, dass es den Vertragscharakter zeigt . Was ist Vertragscharakter? Warum wurde dieses Wortcontract
eingeführt, wenn wir darüber sprecheninterface
?interface
peripheres Verhalten erforderlich ist , warumpublic interface List<E> extends Collection<E> {}
soll dann das Kernverhalten von beschrieben werdenlist
? Dies widerspricht tatsächlich der Antwort von Prasun. BeideCollection<E>
undList<E>
sind hier Schnittstellen.Kurz: Abstrakte Klassen werden zum Modellieren einer Klassenhierarchie ähnlich aussehender Klassen verwendet (z. B. Tier kann abstrakte Klasse sein und Mensch, Löwe, Tiger können konkrete abgeleitete Klassen sein).
UND
Die Schnittstelle wird für die Kommunikation zwischen zwei ähnlichen / nicht ähnlichen Klassen verwendet, wobei der Typ der Klasse, die die Schnittstelle implementiert, keine Rolle spielt (z. B. Höhe kann eine Schnittstelleneigenschaft sein und kann von Mensch, Gebäude, Baum implementiert werden. Es spielt keine Rolle, ob Sie essen können , du kannst schwimmen, du kannst sterben oder so .. es ist nur eine Sache, die du brauchst, um Höhe zu haben (Implementierung in deiner Klasse)).
quelle
Es gibt noch ein paar andere Unterschiede -
Schnittstellen können keine konkreten Implementierungen haben. Abstrakte Basisklassen können. Auf diese Weise können Sie dort konkrete Implementierungen vornehmen. Dies kann es einer abstrakten Basisklasse ermöglichen, tatsächlich einen strengeren Vertrag bereitzustellen, wobei eine Schnittstelle wirklich nur beschreibt, wie eine Klasse verwendet wird. (Die abstrakte Basisklasse kann nicht virtuelle Mitglieder haben, die das Verhalten definieren, wodurch der Autor der Basisklasse mehr Kontrolle erhält.)
In einer Klasse kann mehr als eine Schnittstelle implementiert werden. Eine Klasse kann nur von einer einzelnen abstrakten Basisklasse abgeleitet werden. Dies ermöglicht eine polymorphe Hierarchie unter Verwendung von Schnittstellen, jedoch keine abstrakten Basisklassen. Dies ermöglicht auch eine Pseudo-Multi-Vererbung unter Verwendung von Schnittstellen.
Abstrakte Basisklassen können in v2 + geändert werden, ohne die API zu beschädigen. Änderungen an Schnittstellen sind wichtige Änderungen.
[C # /. NET-spezifisch] Schnittstellen können im Gegensatz zu abstrakten Basisklassen auf Werttypen (Strukturen) angewendet werden. Strukturen können nicht von abstrakten Basisklassen erben. Dadurch können Verhaltensverträge / Nutzungsrichtlinien auf Werttypen angewendet werden.
quelle
Vererbung
Betrachten Sie ein Auto und einen Bus. Sie sind zwei verschiedene Fahrzeuge. Trotzdem haben sie einige gemeinsame Eigenschaften wie Lenkung, Bremsen, Getriebe, Motor usw.
Mit dem Vererbungskonzept kann dies wie folgt dargestellt werden ...
Jetzt ein Fahrrad ...
Und ein Auto ...
Das ist alles über Vererbung . Wir verwenden sie, um Objekte in einfachere Basisformen und ihre Kinder zu klassifizieren, wie wir oben gesehen haben.
Abstrakte Klassen
Abstrakte Klassen sind unvollständige Objekte. Um es besser zu verstehen, betrachten wir noch einmal die Fahrzeuganalogie.
Ein Fahrzeug kann gefahren werden. Recht? Aber verschiedene Fahrzeuge werden auf unterschiedliche Weise gefahren ... Zum Beispiel können Sie ein Auto nicht so fahren, wie Sie ein Fahrrad fahren.
Wie kann man also die Antriebsfunktion eines Fahrzeugs darstellen? Es ist schwieriger zu überprüfen, um welchen Fahrzeugtyp es sich handelt, und es mit einer eigenen Funktion zu fahren. Sie müssten die Fahrerklasse immer wieder ändern, wenn Sie einen neuen Fahrzeugtyp hinzufügen.
Hier kommt die Rolle abstrakter Klassen und Methoden. Sie können die Laufwerksmethode als abstrakt definieren, um anzugeben, dass alle ererbenden untergeordneten Elemente diese Funktion implementieren müssen.
Also, wenn Sie die Fahrzeugklasse ändern ...
Das Fahrrad und das Auto müssen auch angeben, wie es zu fahren ist. Andernfalls wird der Code nicht kompiliert und es wird ein Fehler ausgegeben.
Kurz gesagt ... eine abstrakte Klasse ist eine teilweise unvollständige Klasse mit einigen unvollständigen Funktionen, die die ererbenden Kinder selbst angeben müssen.
Schnittstellen Schnittstellen sind völlig unvollständig. Sie haben keine Eigenschaften. Sie zeigen nur an, dass die erbenden Kinder in der Lage sind, etwas zu tun ...
Angenommen, Sie haben verschiedene Arten von Mobiltelefonen bei sich. Jeder von ihnen hat verschiedene Möglichkeiten, verschiedene Funktionen auszuführen. Beispiel: Rufen Sie eine Person an. Der Hersteller des Telefons gibt an, wie es geht. Hier können die Mobiltelefone eine Nummer wählen - das heißt, sie können gewählt werden. Stellen wir dies als Schnittstelle dar.
Hier definiert der Hersteller des Wählbaren, wie eine Nummer gewählt wird. Sie müssen ihm nur eine Nummer zum Wählen geben.
Bei der Verwendung von Schnittstellen anstelle von abstrakten Klassen muss sich der Verfasser der Funktion, die ein Wählbares verwendet, nicht um seine Eigenschaften kümmern. Beispiel: Hat es einen Touchscreen oder eine Wähltastatur? Ist es ein Festnetztelefon oder ein Mobiltelefon? Sie müssen nur wissen, ob es wählbar ist. erbt (oder implementiert) es die wählbare Schnittstelle?
Und was noch wichtiger ist , wenn Sie eines Tages die Wählscheibe gegen eine andere austauschen
Sie können sicher sein, dass der Code immer noch einwandfrei funktioniert, da die Funktion, die das Wählbare verwendet, nicht (und nicht) von anderen als den in der Wählschnittstelle angegebenen Details abhängt. Beide implementieren eine wählbare Schnittstelle und das ist das einzige, was die Funktion interessiert.
Schnittstellen werden häufig von Entwicklern verwendet, um die Interoperabilität (austauschbare Verwendung) zwischen Objekten sicherzustellen, sofern diese eine gemeinsame Funktion haben (genau wie Sie zu einem Festnetz- oder Mobiltelefon wechseln können, sofern Sie nur eine Nummer wählen müssen). Kurz gesagt, Schnittstellen sind eine viel einfachere Version von abstrakten Klassen ohne Eigenschaften.
Beachten Sie außerdem, dass Sie so viele Schnittstellen implementieren (erben) können, wie Sie möchten, aber nur eine einzelne übergeordnete Klasse erweitern (erben) dürfen.
Weitere Info Abstract Klassen vs Interfaces
quelle
Wenn Sie
java
diese Frage als OOP-Sprache beantworten, führt die Java 8-Version dazu, dass einige der in den obigen Antworten enthaltenen Inhalte veraltet sind. Jetzt kann die Java-Schnittstelle Standardmethoden mit konkreter Implementierung haben.Die Oracle- Website bietet wichtige Unterschiede zwischen
interface
undabstract
Klasse.Verwenden Sie abstrakte Klassen, wenn:
Erwägen Sie die Verwendung von Schnittstellen, wenn:
Serializable
Schnittstelle implementieren .In einfachen Worten möchte ich verwenden
Schnittstelle: Um einen Vertrag durch mehrere unabhängige Objekte zu implementieren
abstrakte Klasse: Um dasselbe oder ein unterschiedliches Verhalten zwischen mehreren verwandten Objekten zu implementieren
Schauen Sie sich das Codebeispiel an, um die Dinge klar zu verstehen: Wie hätte ich den Unterschied zwischen einer Interface- und einer Abstract-Klasse erklären sollen?
quelle
Die Interviewer bellen einen seltsamen Baum an. Für Sprachen wie C # und Java gibt es einen Unterschied, für andere Sprachen wie C ++ jedoch keinen. Die OO-Theorie unterscheidet die beiden nicht, sondern lediglich die Syntax der Sprache.
Eine abstrakte Klasse ist eine Klasse mit Implementierung und Schnittstelle (reine virtuelle Methoden), die vererbt werden. Schnittstellen haben im Allgemeinen keine Implementierung, sondern nur reine virtuelle Funktionen.
In C # oder Java unterscheidet sich eine abstrakte Klasse ohne Implementierung von einer Schnittstelle nur in der Syntax, die zum Erben verwendet wird, und in der Tatsache, dass Sie nur von einer erben können.
quelle
Durch die Implementierung von Schnittstellen erreichen Sie eine Komposition ("has-a" -Beziehungen) anstelle einer Vererbung ("is-a" -Beziehungen). Dies ist ein wichtiges Prinzip, an das Sie sich erinnern sollten, wenn es um Entwurfsmuster geht, bei denen Sie Schnittstellen verwenden müssen, um eine Komposition von Verhaltensweisen anstelle einer Vererbung zu erzielen.
quelle
Ich werde die Details der Schnittstelle und der abstrakten Klasse erläutern. Wenn Sie einen Überblick über die Schnittstelle und die abstrakte Klasse haben, stellen Sie sich zunächst die Frage, wann wir die Schnittstelle und wann wir die abstrakte Klasse verwenden sollten. Bitte überprüfen Sie die unten stehende Erklärung der Interface- und Abstract-Klasse.
Wann sollten wir Interface verwenden?
Wenn Sie nicht über die Implementierung Bescheid wissen, nur wir haben Anforderungsspezifikationen, dann gehen wir mit Schnittstelle
Wann sollten wir Abstract Class verwenden?
Wenn Sie die Implementierung kennen, aber nicht vollständig (teilweise Implementierung), dann gehen wir mit der Abstract-Klasse.
Schnittstelle
Standardmäßig bedeutet jede Methode public abstract, dass die Schnittstelle zu 100% rein abstrakt ist.
Abstrakt
kann eine konkrete Methode und eine abstrakte Methode haben, was eine konkrete Methode ist, die in der abstrakten Klasse implementiert ist. Eine abstrakte Klasse ist eine Klasse, die als abstrakt deklariert ist - sie kann abstrakte Methoden enthalten oder nicht.
Schnittstelle
Wir können die Schnittstelle nicht als privat und geschützt deklarieren
Q. Warum erklären wir Interface nicht als privat und geschützt?
Da die Schnittstellenmethode standardmäßig öffentlich abstrakt ist, deklarieren wir die Schnittstelle nicht als privat und geschützt.
Schnittstellenmethode
Wir können die Schnittstelle auch nicht als privat, geschützt, endgültig, statisch, synchronisiert, nativ deklarieren.
Ich werde den Grund angeben: Warum wir keine synchronisierte Methode deklarieren, weil wir kein Objekt der Schnittstelle erstellen und synchronisieren können, sind Arbeiten am Objekt, und der Grund, warum wir die synchronisierte Methode nicht deklarieren, ist auch nicht anwendbar, weil transiente Arbeit mit synchronisierten Methoden.
Abstrakt
Wir verwenden gerne öffentliche, private endgültige statische Elemente. Dies bedeutet, dass abstrakte Einschränkungen nicht gelten.
Schnittstelle
Variablen werden in Interface standardmäßig als öffentliches statisches Finale deklariert, sodass wir auch nicht als private, geschützte Variable deklariert werden.
Der flüchtige Modifikator ist auch in der Schnittstelle nicht anwendbar, da die Schnittstellenvariable standardmäßig eine öffentliche statische endgültige und endgültige Variable ist. Sie können den Wert nicht ändern, sobald der Wert der Variablen zugewiesen wurde und wenn Sie die Variable der Schnittstelle deklariert haben, müssen Sie die Variable zuweisen.
Und die flüchtige Variable ändert sich ständig, so dass sie entgegengesetzt ist. Aus diesem Grund verwenden wir keine flüchtige Variable in der Schnittstelle.
Abstrakt
Abstrakte Variable muss nicht als öffentliches statisches Finale deklariert werden.
Ich hoffe, dieser Artikel ist nützlich.
quelle
Abstract class must have at lease one abstract method.
Es ist möglich, eine Abstract-Klasse ohne eine Abstract-Methode zu haben, solange Sie sie implementieren. REFERENZ:An abstract class is a class that is declared abstract—it may or may not include abstract methods.
REFERENZQUELLE: docs.oracle.com/javase/tutorial/java/IandI/abstract.htmlKonzeptionell gesehen kann oder kann die Beibehaltung der sprachspezifischen Implementierung, Regeln, Vorteile und das Erreichen eines Programmierziels durch Verwendung von irgendjemandem oder beidem Code / Daten / Eigenschaften, bla bla, einzelne oder mehrere Vererbungen haben oder nicht
1- Abstrakte (oder rein abstrakte) Klasse soll Hierarchie implementieren. Wenn Ihre Geschäftsobjekte strukturell etwas ähnlich aussehen und nur eine Eltern-Kind-Beziehung (Hierarchie) darstellen, werden Vererbungs- / abstrakte Klassen verwendet. Wenn Ihr Geschäftsmodell keine Hierarchie hat, sollte die Vererbung nicht verwendet werden (hier spreche ich nicht über Programmierlogik, z. B. erfordern einige Entwurfsmuster eine Vererbung). Konzeptionell ist die abstrakte Klasse eine Methode zum Implementieren der Hierarchie eines Geschäftsmodells in OOP. Sie hat nichts mit Schnittstellen zu tun. Der Vergleich der abstrakten Klasse mit der Schnittstelle ist bedeutungslos, da beide konzeptionell völlig unterschiedliche Dinge sind. In Interviews wird nur darum gebeten, die Konzepte zu überprüfen, da beide bei der Implementierung ungefähr die gleiche Funktionalität bieten und wir Programmierer normalerweise mehr Wert auf die Codierung legen. [Denken Sie auch daran, dass sich die Abstraktion von der abstrakten Klasse unterscheidet].
2- Eine Schnittstelle ist ein Vertrag, eine vollständige Geschäftsfunktionalität, die durch eine oder mehrere Funktionen dargestellt wird. Deshalb wird es implementiert und nicht vererbt. Ein Geschäftsobjekt (Teil einer Hierarchie oder nicht) kann eine beliebige Anzahl vollständiger Geschäftsfunktionen aufweisen. Es hat nichts mit abstrakten Klassen zu tun, bedeutet Vererbung im Allgemeinen. Zum Beispiel kann ein Mensch LAUFEN, ein Elefant kann LAUFEN, ein Vogel kann LAUFEN usw. Alle diese Objekte unterschiedlicher Hierarchie würden die RUN-Schnittstelle oder die EAT- oder SPEAK-Schnittstelle implementieren. Gehen Sie nicht in die Implementierung, da Sie möglicherweise abstrakte Klassen für jeden Typ implementieren, der diese Schnittstellen implementiert. Ein Objekt jeder Hierarchie kann eine Funktionalität (Schnittstelle) haben, die nichts mit seiner Hierarchie zu tun hat.
Ich glaube, Schnittstellen wurden nicht erfunden, um Mehrfachvererbungen zu erreichen oder öffentliches Verhalten aufzudecken, und in ähnlicher Weise sollen reine abstrakte Klassen Schnittstellen nicht außer Kraft setzen, aber Schnittstelle ist eine Funktionalität, die ein Objekt (über Funktionen dieser Schnittstelle) ausführen kann, und abstrakte Klasse repräsentiert a Eltern einer Hierarchie, um Kinder mit der Kernstruktur (Eigenschaft + Funktionalität) des Elternteils zu erzeugen
Wenn Sie nach dem Unterschied gefragt werden, handelt es sich tatsächlich um einen konzeptionellen Unterschied, nicht um den Unterschied in der sprachspezifischen Implementierung, es sei denn, Sie werden ausdrücklich dazu aufgefordert.
Ich glaube, beide Interviewer hatten einen direkten Unterschied zwischen diesen beiden erwartet, und als Sie versagten, versuchten sie, Sie zu diesem Unterschied zu führen, indem sie ONE als den ANDEREN implementierten
quelle
Für .Net,
Ihre Antwort auf Der zweite Interviewer ist auch die Antwort auf den ersten ... Abstrakte Klassen können implementiert werden, UND Status, Schnittstellen können nicht ...
BEARBEITEN: In einem anderen Fall würde ich nicht einmal den Ausdruck "Unterklasse" (oder den Ausdruck "Vererbung") verwenden, um Klassen zu beschreiben, die "definiert sind, um eine Schnittstelle zu implementieren". Für mich ist eine Schnittstelle eine Definition eines Vertrags, dem eine Klasse entsprechen muss, wenn sie definiert wurde, um diese Schnittstelle zu "implementieren". Es erbt nichts ... Sie müssen alles explizit selbst hinzufügen.
quelle
Schnittstelle : sollte verwendet werden, wenn Sie eine Regel für die Komponenten implizieren möchten, die möglicherweise miteinander in Beziehung stehen oder nicht
Vorteile:
Nachteile:
Abstrakte Klasse : sollte verwendet werden, wenn Sie ein grundlegendes oder Standardverhalten oder eine Implementierung für miteinander verbundene Komponenten wünschen
Vorteile:
Nachteile:
quelle
Ich denke, Ihre Antwort hat ihnen nicht gefallen, weil Sie die technischen Unterschiede anstelle der gestalterischen angegeben haben. Die Frage ist für mich wie eine Trollfrage. Tatsächlich haben Schnittstellen und abstrakte Klassen eine völlig andere Natur, sodass Sie sie nicht wirklich vergleichen können. Ich werde Ihnen meine Vision geben, welche Rolle eine Schnittstelle spielt und welche Rolle eine abstrakte Klasse spielt.
Schnittstelle: Wird verwendet, um einen Vertrag sicherzustellen und eine geringe Kopplung zwischen Klassen herzustellen, um eine wartbarere, skalierbarere und testbarere Anwendung zu erhalten.
abstrakte Klasse: wird nur verwendet, um Code zwischen Klassen mit derselben Verantwortlichkeit zu faktorisieren. Beachten Sie, dass dies der Hauptgrund ist, warum Mehrfachvererbung in OOP eine schlechte Sache ist, da eine Klasse nicht mit vielen Verantwortlichkeiten umgehen sollte (verwenden Sie stattdessen die Komposition ).
Schnittstellen spielen also eine echte architektonische Rolle, während abstrakte Klassen fast nur ein Detail der Implementierung sind (wenn Sie sie natürlich richtig verwenden).
quelle
Dokumente sagen eindeutig, dass eine abstrakte Klasse, die nur abstrakte Methodendeklarationen enthält, stattdessen als Schnittstelle deklariert werden sollte.
Variablen in Schnittstellen sind standardmäßig öffentlich statisch und endgültig. Die Frage könnte wie folgt lauten: Wenn alle Variablen in der abstrakten Klasse öffentlich sind? Nun, sie können im Gegensatz zu den Variablen in Schnittstellen immer noch nicht statisch und nicht endgültig sein.
Abschließend möchte ich noch einen Punkt zu den oben genannten hinzufügen: Abstrakte Klassen sind immer noch Klassen und fallen in einen einzelnen Vererbungsbaum, während Schnittstellen in Mehrfachvererbung vorhanden sein können.
quelle
Das ist meine Meinung.
quelle
Von CLR über C # von Jeffrey Richter kopiert ...
Ich höre oft die Frage: "Soll ich einen Basistyp oder eine Schnittstelle entwerfen?" Die Antwort ist nicht immer eindeutig.
Hier sind einige Richtlinien, die Ihnen helfen könnten:
■■ Beziehung zwischen IS-A und CAN-DO Ein Typ kann nur eine Implementierung erben. Wenn der abgeleitete Typ keine IS-A-Beziehung zum Basistyp beanspruchen kann, verwenden Sie keinen Basistyp. Verwenden Sie eine Schnittstelle. Schnittstellen implizieren eine CAN-DO-Beziehung. Wenn die CAN-DO-Funktionalität zu verschiedenen Objekttypen zu gehören scheint, verwenden Sie eine Schnittstelle. Beispielsweise kann ein Typ Instanzen von sich selbst in einen anderen Typ konvertieren (IConvertible), ein Typ kann eine Instanz von sich selbst serialisieren (ISerializable) usw. Beachten Sie, dass Werttypen von System.ValueType abgeleitet werden müssen und daher nicht abgeleitet werden können aus einer beliebigen Basisklasse. In diesem Fall müssen Sie eine CAN-DO-Beziehung verwenden und eine Schnittstelle definieren.
■■ Benutzerfreundlichkeit Für Sie als Entwickler ist es im Allgemeinen einfacher, einen neuen Typ zu definieren, der von einem Basistyp abgeleitet ist, als alle Methoden einer Schnittstelle zu implementieren. Der Basistyp kann viele Funktionen bereitstellen, sodass der abgeleitete Typ wahrscheinlich nur relativ kleine Änderungen an seinem Verhalten erfordert. Wenn Sie eine Schnittstelle angeben, muss der neue Typ alle Mitglieder implementieren.
■■ Konsistente Implementierung Unabhängig davon, wie gut ein Schnittstellenvertrag dokumentiert ist, ist es sehr unwahrscheinlich, dass jeder den Vertrag zu 100 Prozent korrekt implementiert. In der Tat leidet COM unter genau diesem Problem, weshalb einige COM-Objekte nur mit Microsoft Word oder Windows Internet Explorer ordnungsgemäß funktionieren. Indem Sie einen Basistyp mit einer guten Standardimplementierung bereitstellen, verwenden Sie zunächst einen Typ, der funktioniert und gut getestet ist. Sie können dann Teile ändern, die geändert werden müssen.
■■ Versionierung Wenn Sie dem Basistyp eine Methode hinzufügen, erbt der abgeleitete Typ die neue Methode, Sie verwenden zunächst einen funktionierenden Typ und der Quellcode des Benutzers muss nicht einmal neu kompiliert werden. Das Hinzufügen eines neuen Elements zu einer Schnittstelle zwingt den Erben der Schnittstelle, seinen Quellcode zu ändern und neu zu kompilieren.
quelle
abstract class
.Eine Schnittstelle definiert einen Vertrag für einen Dienst oder eine Reihe von Diensten. Sie bieten Polymorphismus auf horizontale Weise, indem zwei völlig unabhängige Klassen dieselbe Schnittstelle implementieren können, aber austauschbar als Parameter für den Typ der von ihnen implementierten Schnittstelle verwendet werden, da beide Klassen versprochen haben, die von der Schnittstelle definierten Dienste zu erfüllen. Schnittstellen enthalten keine Implementierungsdetails.
Eine abstrakte Klasse definiert eine Basisstruktur für ihre Unterklassen und optional eine teilweise Implementierung. Abstrakte Klassen bieten Polymorphismus in vertikaler, aber gerichteter Weise, indem jede Klasse, die die abstrakte Klasse erbt, als Instanz dieser abstrakten Klasse behandelt werden kann, aber nicht umgekehrt. Abstrakte Klassen können und enthalten häufig Implementierungsdetails, können jedoch nicht selbst instanziiert werden - nur ihre Unterklassen können "neu erstellt" werden.
C # ermöglicht wohlgemerkt auch die Vererbung von Schnittstellen.
quelle
Die meisten Antworten konzentrieren sich auf den technischen Unterschied zwischen abstrakter Klasse und Schnittstelle, aber da eine Schnittstelle technisch gesehen im Grunde eine Art abstrakte Klasse ist (eine ohne Daten oder Implementierung), denke ich, dass dies konzeptionell ist Unterschied weitaus interessanter ist, und das könnte sein Die Interviewer sind hinterher.
Eine Schnittstelle ist eine Vereinbarung . Darin heißt es: "So werden wir miteinander reden". Es kann keine Implementierung hat , weil es nicht hat sollte jede Implementierung haben. Es ist ein Vertrag. Es ist wie bei den
.h
Header-Dateien in C.Eine abstrakte Klasse ist eine unvollständige Implementierung . Eine Klasse kann eine Schnittstelle implementieren oder nicht, und eine abstrakte Klasse muss sie nicht vollständig implementieren. Eine abstrakte Klasse ohne Implementierung ist nutzlos, aber völlig legal.
Grundsätzlich geht es in jeder abstrakten oder nicht abstrakten Klasse darum, was sie ist , während es bei einer Schnittstelle darum geht, wie Sie sie verwenden . Zum Beispiel:
Animal
könnte eine abstrakte Klasse sein, die einige grundlegende Stoffwechselfunktionen implementiert und abstrakte Methoden für Atmung und Fortbewegung spezifiziert, ohne eine Implementierung zu geben, da sie keine Ahnung hat, ob sie durch Kiemen oder Lungen atmen soll und ob sie fliegt, schwimmt, geht oder kriecht.Mount
Auf der anderen Seite könnte es sich um eine Schnittstelle handeln, die angibt, dass Sie das Tier reiten können, ohne zu wissen, um welche Art von Tier es sich handelt (oder ob es überhaupt ein Tier ist!).Die Tatsache, dass eine Schnittstelle hinter den Kulissen im Grunde eine abstrakte Klasse mit nur abstrakten Methoden ist, spielt keine Rolle. Konzeptionell erfüllen sie völlig unterschiedliche Rollen.
quelle
Da Sie vielleicht das theoretische Wissen von den Experten erhalten haben, verbringe ich nicht viele Worte damit, all diese hier zu wiederholen, sondern lassen Sie mich anhand eines einfachen Beispiels erklären, wo wir und verwenden können
Interface
und was nichtAbstract class
.Stellen Sie sich vor, Sie entwerfen eine Anwendung, um alle Funktionen von Autos aufzulisten. In verschiedenen Punkten benötigen Sie eine gemeinsame Vererbung, da einige der Eigenschaften wie DigitalFuelMeter, Klimaanlage, Sitzverstellung usw. für alle Fahrzeuge gleich sind. Ebenso benötigen wir nur für einige Klassen eine Vererbung, da einige der Eigenschaften wie das Bremssystem (ABS, EBD) nur für einige Autos gelten.
Die folgende Klasse dient als Basisklasse für alle Autos:
Bedenken Sie, dass wir für jedes Auto eine eigene Klasse haben.
Bedenken Sie, dass wir eine Methode zur Vererbung der Bremstechnologie für die Autos Verna und Cruze benötigen (gilt nicht für Alto). Obwohl beide die Bremstechnologie verwenden, ist die "Technologie" unterschiedlich. Wir erstellen also eine abstrakte Klasse, in der die Methode als abstrakt deklariert wird und in ihren untergeordneten Klassen implementiert werden sollte.
Jetzt versuchen wir, von dieser abstrakten Klasse zu erben, und die Art des Bremssystems ist in Verna und Cruze implementiert:
Sehen Sie das Problem in den beiden oben genannten Klassen? Sie erben von mehreren Klassen, die C # .Net nicht zulässt, obwohl die Methode in den untergeordneten Klassen implementiert ist. Hier kommt die Notwendigkeit der Schnittstelle.
Und die Implementierung ist unten angegeben:
Jetzt können Verna und Cruze mit Hilfe von Interface mit ihrer eigenen Art von Bremstechnologien eine Mehrfachvererbung erreichen.
quelle
Schnittstellen sind eine leichte Möglichkeit, ein bestimmtes Verhalten durchzusetzen. Das ist eine Art zu denken.
quelle
Diese Antworten sind allzu lang.
Schnittstellen dienen zum Definieren von Verhaltensweisen.
Abstrakte Klassen dienen dazu, ein Ding selbst zu definieren, einschließlich seines Verhaltens. Aus diesem Grund erstellen wir manchmal eine abstrakte Klasse mit einigen zusätzlichen Eigenschaften, die eine Schnittstelle erben.
Dies erklärt auch, warum Java nur die Einzelvererbung für Klassen unterstützt, die Schnittstellen jedoch nicht einschränkt. Weil ein konkretes Objekt nicht verschiedene Dinge sein kann, aber es kann verschiedene Verhaltensweisen haben.
quelle
1) Eine Schnittstelle kann als reine abstrakte Klasse angesehen werden, ist dieselbe, aber trotzdem nicht dieselbe, um eine Schnittstelle zu implementieren und von einer abstrakten Klasse zu erben. Wenn Sie von dieser reinen abstrakten Klasse erben, definieren Sie eine Hierarchie -> Vererbung, wenn Sie die Schnittstelle implementieren, die Sie nicht sind, und Sie können so viele Schnittstellen implementieren, wie Sie möchten, aber Sie können nur von einer Klasse erben.
2) Sie können eine Eigenschaft in einer Schnittstelle definieren, daher muss die Klasse, die diese Schnittstelle implementiert, diese Eigenschaft haben.
Zum Beispiel:
Die Klasse, die diese Schnittstelle implementiert, muss eine solche Eigenschaft haben.
quelle
Obwohl diese Frage ziemlich alt ist, möchte ich noch einen weiteren Punkt zugunsten von Schnittstellen hinzufügen:
Schnittstellen können mit beliebigen Tools für die Abhängigkeitsinjektion injiziert werden, wobei die Injektion als abstrakte Klasse nur von sehr wenigen unterstützt wird.
quelle
Aus einer anderen Antwort von mir geht es hauptsächlich darum, wann man eins gegen das andere verwendet:
quelle
Schnittstellentypen vs. abstrakte Basisklassen
Angepasst an Pro C # 5.0 und das .NET 4.5 Framework- Buch.
Der Schnittstellentyp scheint einer abstrakten Basisklasse sehr ähnlich zu sein. Denken Sie daran, dass eine Klasse, die als abstrakt markiert ist, eine beliebige Anzahl von abstrakten Elementen definieren kann, um eine polymorphe Schnittstelle für alle abgeleiteten Typen bereitzustellen. Selbst wenn eine Klasse eine Reihe von abstrakten Elementen definiert, ist es auch frei, eine beliebige Anzahl von Konstruktoren, Felddaten, nicht abstrakten Elementen (mit Implementierung) usw. zu definieren. Schnittstellen enthalten dagegen nur abstrakte Elementdefinitionen. Die von einer abstrakten übergeordneten Klasse eingerichtete polymorphe Schnittstelle weist eine wesentliche Einschränkung auf, da nur abgeleitete Typen die vom abstrakten übergeordneten Element definierten Elemente unterstützen. In größeren Softwaresystemen ist es jedoch sehr üblich, mehrere Klassenhierarchien zu entwickeln, die über System.Object hinaus kein gemeinsames übergeordnetes Element haben. Da abstrakte Elemente in einer abstrakten Basisklasse nur für abgeleitete Typen gelten, können wir keine Typen in verschiedenen Hierarchien konfigurieren, um dieselbe polymorphe Schnittstelle zu unterstützen. Angenommen, Sie haben die folgende abstrakte Klasse definiert:
Aufgrund dieser Definition können nur Mitglieder, die CloneableType erweitern, die Clone () -Methode unterstützen. Wenn Sie eine neue Gruppe von Klassen erstellen, die diese Basisklasse nicht erweitern, können Sie diese polymorphe Schnittstelle nicht erhalten. Sie können sich auch daran erinnern, dass C # keine Mehrfachvererbung für Klassen unterstützt. Wenn Sie also einen MiniVan erstellen möchten, der ein Auto und ein klonbarer Typ ist, können Sie dies nicht tun:
Wie Sie sich vorstellen können, helfen Schnittstellentypen. Nachdem eine Schnittstelle definiert wurde, kann sie von jeder Klasse oder Struktur, in jeder Hierarchie, in jedem Namespace oder jeder Assembly (geschrieben in einer beliebigen .NET-Programmiersprache) implementiert werden. Wie Sie sehen können, sind Schnittstellen stark polymorph. Betrachten Sie die Standard-.NET-Schnittstelle mit dem Namen ICloneable, die im System-Namespace definiert ist. Diese Schnittstelle definiert eine einzelne Methode namens Clone ():
quelle
Antwort auf die zweite Frage: Die in
public
definierte Variableinterface
iststatic final
standardmäßig, während diepublic
Variable in derabstract
Klasse eine Instanzvariable ist.quelle
Natürlich ist es wichtig, das Verhalten der Schnittstelle und der abstrakten Klasse in OOP zu verstehen (und wie Sprachen damit umgehen), aber ich denke, es ist auch wichtig zu verstehen, was genau jeder Begriff bedeutet. Können Sie sich vorstellen, dass der
if
Befehl nicht genau der Bedeutung des Begriffs entspricht? Tatsächlich reduzieren einige Sprachen sogar noch mehr die Unterschiede zwischen einer Schnittstelle und einer Zusammenfassung. Wenn die beiden Begriffe eines Tages zufällig fast identisch funktionieren, können Sie zumindest selbst definieren, wo (und warum) einer von ihnen sein soll benutzt für.Wenn Sie einige Wörterbücher und andere Schriftarten durchlesen, finden Sie möglicherweise unterschiedliche Bedeutungen für denselben Begriff, haben jedoch einige gemeinsame Definitionen. Ich denke, diese beiden Bedeutungen, die ich auf dieser Seite gefunden habe, sind wirklich sehr, sehr gut und geeignet.
Schnittstelle:
Abstrakt:
Beispiel:
Sie haben ein Auto gekauft und es braucht Kraftstoff.
Ihr Automodell ist ein
XYZ
GenreABC
, also ein konkretes Auto, eine bestimmte Instanz eines Autos. Ein Auto ist kein echtes Objekt. Tatsächlich ist es eine abstrakte Reihe von Standards (Qualitäten), um ein bestimmtes Objekt zu erstellen. Kurz gesagt, Auto ist eine abstrakte Klasse , es ist "etwas, das in sich die wesentlichen Eigenschaften von etwas Umfangreicherem oder Allgemeinerem konzentriert" .Der einzige Kraftstoff, der der manuellen Spezifikation des Fahrzeugs entspricht, sollte zum Auffüllen des Fahrzeugtanks verwendet werden. In der Realität gibt es nichts, was Sie daran hindert, Kraftstoff nachzufüllen, aber der Motor funktioniert nur mit dem angegebenen Kraftstoff ordnungsgemäß. Daher ist es besser, die Anforderungen zu erfüllen. Die Anforderungen besagen, dass es wie andere Autos des gleichen Genres akzeptiert
ABC
einen Standard-Kraftstoffsatz .In einer objektorientierten Ansicht sollte Kraftstoff für das Genre
ABC
nicht als Klasse deklariert werden, da es keinen konkreten Kraftstoff für ein bestimmtes Genre des Autos gibt. Obwohl Ihr Auto eine abstrakte Klasse Kraftstoff oder Fahrzeugkraftstoff akzeptieren könnte, müssen Sie sich daran erinnern, dass nur ein Teil des vorhandenen Fahrzeugkraftstoffs der Spezifikation entspricht, die die Anforderungen in Ihrem Autohandbuch implementiert. Kurz gesagt, sie sollten die Schnittstelle implementierenABCGenreFuel
, die "... es ermöglicht, dass separate und manchmal inkompatible Elemente effektiv koordiniert werden" .Nachtrag
Darüber hinaus sollten Sie die Bedeutung des Begriffs Klasse berücksichtigen, der (von derselben zuvor erwähnten Site) lautet:
Klasse:
Auf diese Weise sollte eine Klasse (oder abstrakte Klasse) nicht nur gemeinsame Attribute (wie eine Schnittstelle) darstellen, sondern eine Art Gruppe mit gemeinsamen Attributen. Eine Schnittstelle muss keine Art darstellen. Es muss gemeinsame Attribute darstellen. Auf diese Weise denke ich, dass Klassen und abstrakte Klassen verwendet werden können, um Dinge darzustellen, die ihre Aspekte nicht oft ändern sollten, wie ein Mensch ein Säugetier, weil es einige Arten darstellt. Arten sollten sich nicht so oft ändern.
quelle
Aus Codierungsperspektive
Eine Schnittstelle kann eine abstrakte Klasse ersetzen, wenn die abstrakte Klasse nur abstrakte Methoden enthält. Andernfalls bedeutet das Ändern der Abstract-Klasse in eine Schnittstelle, dass Sie die von Inheritance bereitgestellte Wiederverwendbarkeit von Code verlieren.
Aus gestalterischer Sicht
Behalten Sie es als abstrakte Klasse bei, wenn es sich um eine "Ist eine" Beziehung handelt und Sie eine Teilmenge oder alle Funktionen benötigen. Behalten Sie es als Schnittstelle bei, wenn es sich um eine "Sollte" -Beziehung handelt.
Entscheiden Sie, was Sie benötigen: nur die Durchsetzung der Richtlinien oder die Wiederverwendbarkeit des Codes UND die Richtlinie.
quelle
Einige andere Unterschiede:
Abstrakte Klassen können statische Methoden, Eigenschaften, Felder usw. und Operatoren haben, Schnittstellen nicht. Der Cast-Operator erlaubt das Casting zu / von der abstrakten Klasse, aber nicht das Casting zur / von der Schnittstelle.
Sie können die abstrakte Klasse so gut wie alleine verwenden, auch wenn sie niemals implementiert ist (über ihre statischen Elemente) und Sie können die Schnittstelle in keiner Weise alleine verwenden.
quelle