it-swarm.com.de

Schnittstelle vs. abstrakte Klasse (allgemeines OO)

Ich hatte kürzlich zwei Telefoninterviews, in denen ich nach den Unterschieden zwischen einem Interface- und einem Abstract-Kurs 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 Konkretes erwähne und ich weiß nicht, was es ist.

Aus meiner Erfahrung halte ich das Folgende für richtig. Wenn mir ein wichtiger Punkt fehlt, lass es mich wissen.

Schnittstelle:

Jede einzelne in einer Schnittstelle deklarierte Methode muss in der Unterklasse implementiert werden. __ In einer Schnittstelle können nur Ereignisse, Delegierte, 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 Abstract-Klasse kann normale Methoden mit Implementierungen haben. Abstrakte Klassen können neben Events, Delegates, Properties und Methods auch Klassenvariablen enthalten. Eine Klasse kann nur eine abstrakte Klasse implementieren, da in C # keine Multi-Vererbung vorhanden ist.

  1. 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 die oben erwähnte Vererbung, richtig?

  2. Ein anderer Interviewer fragte mich, was wäre, wenn Sie eine öffentliche Variable in der Benutzeroberfläche hätten. Wie würde sich das als in 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

1286
Houman

Während Ihre Frage darauf hinweist, dass es sich um "allgemeines OO" handelt, scheint sie sich auf die Verwendung von .Net zu konzentrieren.

In .NET (ähnlich für Java):

  • schnittstellen können keinen Zustand oder Implementierung haben
  • eine Klasse, die eine Schnittstelle implementiert, muss eine Implementierung aller Methoden dieser Schnittstelle bereitstellen
  • abstrakte Klassen können Status (Datenmitglieder) und/oder Implementierung (Methoden) enthalten
  • abstrakte Klassen können ohne Implementierung der abstrakten Methoden vererbt werden (obwohl eine solche abgeleitete Klasse selbst abstrakt ist).
  • schnittstellen können mehrfach vererbt sein, abstrakte Klassen möglicherweise nicht (dies ist wahrscheinlich der entscheidende Grund, warum Schnittstellen getrennt von abtract-Klassen existieren sollen - sie ermöglichen eine Implementierung von Mehrfachvererbung, die viele Probleme des allgemeinen MI entfernt).

Als allgemeine OO - Ausdrücke sind die Unterschiede nicht notwendigerweise genau definiert. Beispielsweise gibt es C++ - Programmierer, die ähnliche starre Definitionen enthalten können (Schnittstellen sind eine strikte Teilmenge abstrakter Klassen, die keine Implementierung enthalten können), während manche sagen, dass eine abstrakte Klasse mit einigen Standardimplementierungen immer noch eine Schnittstelle oder ein nicht abstraktes Element ist Klasse kann immer noch eine Schnittstelle definieren.

In der Tat gibt es ein C++ - Idiom namens Non-Virtual Interface (NVI), bei dem die öffentlichen Methoden nicht-virtuelle Methoden sind, die sich an private virtuelle Methoden "denken" lassen: 

676
Michael Burr

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 qualifiziert, etwas zu fliegen, und musste an einem Flugzeugmuster-Training teilnehmen. Nachdem ich mich qualifiziert hatte, war ich Pilot (abstrakte Klasse) und C-141-Pilot (konkrete Klasse). Bei einer meiner Aufgaben bekam ich eine zusätzliche Aufgabe: den Sicherheitsbeauftragten. Jetzt war ich noch Pilot und C-141-Pilot, aber ich habe auch die Aufgaben des Sicherheitsbeauftragten wahrgenommen (ich habe sozusagen ISafetyOfficer implementiert). Ein Pilot war kein Sicherheitsoffizier, andere hätten es auch tun können.

Alle USAF-Piloten müssen bestimmten Vorschriften der gesamten Luftwaffe folgen. Alle Piloten der C-141 (oder F-16 oder T-38) sind „USAF-Piloten“. Jeder kann ein Sicherheitsoffizier sein. Zusammenfassend also:

  • Pilot: abstrakte Klasse
  • C-141 Pilot: Betonklasse
  • ISafety Officer: Schnittstelle

hinweis hinzugefügt: Dies war eine Analogie zur Erklärung des Konzepts, keine Kodierungsempfehlung. Siehe die verschiedenen Kommentare unten, die Diskussion ist interessant.

796
Jay

Ich denke, die Antwort, die sie suchen, ist der grundlegende oder philosophische Unterschied zwischen OPPS.

Die abstrakte Klassenvererbung wird verwendet, wenn die abgeleitete Klasse die Haupteigenschaften und das Verhalten der abstrakten Klasse gemeinsam hat. Die Art von Verhalten, die die Klasse tatsächlich definiert.

Andererseits wird Schnittstellenvererbung verwendet, wenn die Klassen ein peripheres Verhalten aufweisen, das die abgeleitete Klasse nicht unbedingt definiert.

Für zB Ein Auto und ein LKW haben viele Kernmerkmale und Verhaltensweisen einer abstrakten Automobile-Klasse, aber auch ein gewisses peripheres Verhalten, wie etwa Generate-Auspuff, das auch Nichtfahrzeugklassen wie Drillers oder PowerGenerators gemeinsam sind und nicht unbedingt ein Auto oder einen Truck definieren , also können Car, Truck, Driller und PowerGenerator dieselbe Schnittstelle IExhaust verwenden.

207
Prasun

Kurz: Abstrakte Klassen werden für Modellierung eine Klassenhierarchie von ähnlich aussehenden Klassen verwendet (Zum Beispiel können Animal abstrakte Klassen sein und Human, Lion, Tiger können konkrete abgeleitete Klassen sein.)

UND 

Interface wird für Kommunikation zwischen 2 ähnlichen/nicht ähnlichen Klassen verwendet, wobei der Typ der Klasse, die Interface implementiert, nicht berücksichtigt wird (z. B. Height kann eine Interface-Eigenschaft sein und von Human, Building, Tree implementiert werden. Es spielt keine Rolle Wenn du essen kannst, kannst du schwimmen, du kannst sterben oder irgendetwas ... es ist nur eine Sache, die du für die Höhe brauchst (Implementierung in deinem Unterricht). 

180
Dhananjay

Es gibt ein paar andere Unterschiede -

Schnittstellen können keine konkreten Implementierungen haben. Abstrakte Basisklassen können. Dadurch können Sie dort konkrete Implementierungen bereitstellen. Dadurch kann eine abstrakte Basisklasse tatsächlich einen strengeren Vertrag bereitstellen, wobei eine Schnittstelle wirklich nur beschreibt, wie eine Klasse verwendet wird. (Die abstrakte Basisklasse kann über nicht-virtuelle Mitglieder verfügen, 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 nicht abstrakten Basisklassen. Dies ermöglicht auch eine Pseudo-Multi-Vererbung unter Verwendung von Schnittstellen.

Abstrakte Basisklassen können in Version 2 + geändert werden, ohne dass die API beschädigt wird. Änderungen an Schnittstellen sind bahnbrechend.

[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.

76
Reed Copsey

Vererbung
Betrachten Sie ein Auto und einen Bus. Sie sind zwei verschiedene Fahrzeuge. Dennoch haben sie einige gemeinsame Eigenschaften wie Lenkung, Bremsen, Getriebe, Motor usw.
Mit dem Vererbungskonzept kann dies folgendermaßen dargestellt werden:.

public class Vehicle {
    private Driver driver;
    private Seat[] seatArray; //In Java and most of the Object Oriented Programming(OOP) languages, square brackets are used to denote arrays(Collections).
    //You can define as many properties as you want here ...
}

Jetzt ein Fahrrad ... 

public class Bicycle extends Vehicle {
    //You define properties which are unique to bicycles here ...
    private Pedal pedal;
}

Und ein Auto ...

public class Car extends Vehicle {
    private Engine engine;
    private Door[] doors;
}

Das ist alles über Vererbung. Wir verwenden sie zur Klassifizierung von Objekten in einfachere Basisformulare und deren Kinder, wie wir oben gesehen haben.

Abstrakte Klassen

Abstrakte Klassen sind unvollständige Objekte. Um es weiter zu verstehen, betrachten wir noch einmal die Fahrzeuganalogie.
Ein Fahrzeug kann gefahren werden. Recht? Unterschiedliche Fahrzeuge werden jedoch auf unterschiedliche Weise gefahren ... Zum Beispiel können Sie nicht genauso wie beim Fahrradfahren ein Auto fahren.
Wie stellt man die Fahrfunktion eines Fahrzeugs dar? Es ist schwieriger zu prüfen, um welche Art von Fahrzeug es sich handelt und es mit seiner eigenen Funktion fahren. Sie müssen die Fahrerklasse immer wieder ändern, wenn Sie einen neuen Fahrzeugtyp hinzufügen.
Hier kommt die Rolle von abstrakten Klassen und Methoden. Sie können die Antriebsmethode als abstrakt definieren, um anzugeben, dass alle erbenden Kinder diese Funktion implementieren müssen.
Wenn Sie also die Fahrzeugklasse ändern ...

//......Code of Vehicle Class
abstract public void drive();
//.....Code continues

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 erbenden Kinder angeben müssen.

Schnittstellen Schnittstellen sind völlig unvollständig. Sie haben keine Eigenschaften. Sie zeigen nur, dass die erbenden Kinder in der Lage sind, etwas zu tun ...
Angenommen, Sie haben verschiedene Arten von Mobiltelefonen dabei. Jeder von ihnen hat verschiedene Möglichkeiten, verschiedene Funktionen auszuführen. ZB: eine Person anrufen. Der Hersteller des Telefons gibt an, wie es geht. Hier können die Mobiltelefone eine Nummer wählen, dh sie können gewählt werden. Lassen Sie uns dies als Schnittstelle darstellen.

public interface Dialable {
    public void dial(Number n);
}

Hier legt der Hersteller des Dialable fest, wie eine Nummer gewählt wird. Sie müssen ihm nur eine Nummer zum Wählen geben. 

// Makers define how exactly dialable work inside.

Dialable PHONE1 = new Dialable() {
    public void dial(Number n) {
        //Do the phone1's own way to dial a number
    }
}

Dialable PHONE2 = new Dialable() {
    public void dial(Number n) {
        //Do the phone2's own way to dial a number
    }
}


//Suppose there is a function written by someone else, which expects a Dialable
......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE1;
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

Durch die Verwendung von Schnittstellen anstelle von abstrakten Klassen muss sich der Writer der Funktion, die ein Dialable verwendet, keine Gedanken über seine Eigenschaften machen. Bsp .: Hat es einen Touchscreen oder eine Wähltastatur? Handelt es sich um ein Festnetztelefon oder ein Mobiltelefon? Sie müssen nur wissen, ob es wählbar ist. Erbt (oder implementiert) die dialable-Schnittstelle. 

Und, was noch wichtiger ist, wenn Sie eines Tages das Dialable mit einem anderen wechseln

......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE2; // <-- changed from PHONE1 to PHONE2
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

Sie können sicher sein, dass der Code weiterhin einwandfrei funktioniert, da die Funktion, die das Wählbare verwendet, nicht von den Details abhängt, die von den Angaben in der Wählbaren Benutzeroberfläche angegeben werden. Beide implementieren eine Dialable-Schnittstelle und das ist das einzige, worum sich die Funktion kümmert.

Schnittstellen werden häufig von Entwicklern verwendet, um die Interoperabilität zwischen Objekten sicherzustellen (austauschbar zu verwenden), sofern sie eine gemeinsame Funktion haben (so wie Sie auf ein Festnetz oder ein Mobiltelefon wechseln können, sofern Sie nur eine Nummer wählen müssen). Kurz gesagt, Schnittstellen sind eine viel einfachere Version abstrakter Klassen ohne Eigenschaften.
Beachten Sie außerdem, dass Sie beliebig viele Schnittstellen implementieren (erben) können, aber nur eine einzige übergeordnete Klasse erweitern (erben). 

Weitere InformationenAbstrakte Klassen gegen Schnittstellen

66
fz_salam

Wenn Sie Java als OOP -Sprache betrachten, um diese Frage zu beantworten, verursacht Java 8 einen Teil des Inhalts der obigen Antworten als veraltet. Die Java-Schnittstelle kann jetzt über Standardmethoden mit konkreter Implementierung verfügen. 

Oracle website bietet die wichtigsten Unterschiede zwischen der Klasse interface und der Klasse abstract.

Erwägen Sie die Verwendung abstrakter Klassen, wenn:

  1. Sie möchten Code unter mehreren eng miteinander verwandten Klassen teilen.
  2. Sie erwarten, dass Klassen, die Ihre abstrakte Klasse erweitern, viele allgemeine Methoden oder Felder aufweisen oder andere Zugriffsmodifizierer als public (wie protected und private) erfordern.
  3. Sie möchten nicht statische oder nicht abschließende Felder deklarieren. 

Erwägen Sie die Verwendung von Interfaces, wenn:

  1. Sie erwarten, dass nicht verknüpfte Klassen Ihre Schnittstelle implementieren. Beispielsweise können viele nicht zusammenhängende Objekte die Serializable-Schnittstelle implementieren.
  2. Sie möchten das Verhalten eines bestimmten Datentyps angeben, ohne sich jedoch darum zu kümmern, wer sein Verhalten implementiert.
  3. Sie möchten die Mehrfachvererbung des Typs nutzen.

In einfachen Worten möchte ich verwenden

Schnittstelle: Zum Implementieren eines Vertrages durch mehrere nicht verbundene Objekte

abstrakte Klasse: Zum Implementieren des gleichen oder eines unterschiedlichen Verhaltens unter mehreren verwandten Objekten 

Sehen Sie sich Codebeispiele an, um die Dinge klar zu verstehen: Wie hätte ich den Unterschied zwischen einer Schnittstelle und einer abstrakten Klasse erklären sollen?

37
Ravindra babu

Die Interviewer bellen einen seltsamen Baum auf. Bei Sprachen wie C # und Java gibt es einen Unterschied, bei anderen Sprachen wie C++ gibt es keinen Unterschied. 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 wird. 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 verwendeten Syntax und der Tatsache, dass Sie nur von einer erben können.

32
Steve Rowe

Durch die Implementierung von Schnittstellen erreichen Sie Komposition ("has-a" -Beziehungen) anstelle von Vererbung ("is-a" -Beziehungen). Dies ist ein wichtiges Prinzip, an das Sie denken sollten, wenn es beispielsweise um Entwurfsmuster geht, bei denen Sie Schnittstellen verwenden müssen, um eine Zusammensetzung von Verhalten anstelle von Vererbung zu erhalten.

31
TheTXI

ich werde Tiefe Details von Interface und Abstract class erklären. Wenn Sie einen Überblick über Interface und Abstract-Klasse haben, wird Ihnen die erste Frage in den Sinn kommen, wann wir Interface verwenden sollten und wann wir Abstract-Klasse verwenden sollen Interface und Abstract-Klasse.

  1. Wann sollten wir Interface verwenden?

    wenn Sie nichts über die Implementierung wissen, haben wir nur Anforderungsspezifikationen, dann gehen wir mit Interface 

  2. Wann sollten wir Abstract Class verwenden?

    Wenn Sie die Implementierung kennen, aber nicht vollständig (teilweise Implementierung), dann gehen wir zur abstrakten Klasse. 

    Schnittstelle

    standardmäßig bedeutet jede öffentliche Methode, dass die Schnittstelle zu 100% rein abstrakt ist.

    Abstrakt

    kann eine konkrete Methode und eine abstrakte Methode haben, was ist eine konkrete Methode, die eine Implementierung in der abstrakten Klasse .__ haben. Eine abstrakte Klasse ist eine als abstrakt deklarierte Klasse. 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?

    Denn standardmäßig ist die Schnittstellenmethode öffentlich abstrakt, weshalb wir die Schnittstelle nicht als privat und geschützt deklarieren.

    Schnittstellenmethode
    Außerdem können wir die Schnittstelle nicht als privat, geschützt, endgültig, statisch, synchronisiert, nativ deklarieren.

    ich werde den Grund angeben: Warum deklarieren wir keine synchronisierte Methode, weil wir kein Objekt der Schnittstelle erstellen und synchronisieren können, ist die Arbeit an dem Objekt so und aus diesem Grund, weshalb wir nicht die synchronisierte Methode .__ deklarieren. Transientenkonzept sind auch nicht anwendbar, da transientes Arbeiten synchronisiert ist.

    Abstrakt  

    wir werden gerne mit öffentlichen, privaten endgültigen statischen Daten verwendet .... bedeutet, dass keine Einschränkungen abstrakt anwendbar sind.

    Schnittstelle

    Variablen werden in Interface standardmäßig als public static final deklariert. Daher werden wir auch nicht als private, geschützte Variablen deklariert.

    Der flüchtige Modifikator ist auch nicht auf die Schnittstelle anwendbar, da die Schnittstellenvariable standardmäßig eine öffentliche statische endgültige und eine endgültige Variable ist. Sie können den Wert nicht mehr ändern, wenn er den Wert in eine Variable überträgt. Sobald Sie eine Variable in der Schnittstelle deklariert haben, müssen Sie die Variable zuweisen.

    Und die volatile Variable ändert sich ständig und ist daher opp. Das ist der Grund, warum wir keine flüchtigen Variablen in der Schnittstelle verwenden.

    Abstrakt

    Abstrakte Variable muss nicht als public static final deklariert werden.

ich hoffe, dass dieser Artikel nützlich ist.

25
JegsVala

Konzeptionell gesehen kann die Beibehaltung der sprachspezifischen Implementierung, der Regeln, der Vorteile und des Erreichens eines Programmierziels durch die Verwendung von einem oder beiden Personen Code/Daten/Eigenschaften (bla bla bla), einzelne oder mehrere Vererbungen außer Betracht lassen

1- Abstract (oder pure abstract) Klasse soll Hierarchie implementieren. Wenn Ihre Geschäftsobjekte etwas strukturell ähnlich aussehen und nur eine Beziehung zwischen Eltern und Kind (Hierarchie) darstellen, werden Vererbungs-/abstrakte Klassen verwendet. Wenn Ihr Geschäftsmodell keine Hierarchie hat, sollte Vererbung nicht verwendet werden (hier geht es nicht um Programmierlogik, z. B. erfordern einige Entwurfsmuster Vererbung). Konzeptionell ist abstrakte Klasse eine Methode zum Implementieren der Hierarchie eines Geschäftsmodells in OOP. Sie hat nichts mit Interfaces zu tun. Der Vergleich von abstrakter Klasse mit Interface ist bedeutungslos, da beide konzeptionell völlig verschiedene Dinge sind. In Interviews wird lediglich nachgefragt Konzepte, weil es so aussieht, als würden sie bei der Implementierung etwas gleiche Funktionalität bieten, und wir Programmierer legen in der Regel mehr Wert auf die Codierung. [Denken Sie daran, dass Abstraktion sich von der abstrakten Klasse unterscheidet].

2- Eine Schnittstelle ist ein Vertrag, eine vollständige Geschäftsfunktionalität, die durch eine oder mehrere Funktionen repräsentiert 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. Beispielsweise kann ein Mensch RUN ausführen, ein Elefant RUN, ein Vogel RUN usw., und all diese Objekte unterschiedlicher Hierarchie würden die RUN-Schnittstelle oder die EAT- oder SPEAK-Schnittstelle implementieren. Gehen Sie nicht in die Implementierung über, 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, Interfaces wurden nicht erfunden, um mehrere Vererbungen zu erreichen oder um das Verhalten der Öffentlichkeit sichtbar zu machen. In ähnlicher Weise überschreiben rein abstrakte Klassen keine Interfaces, sondern Interface ist eine Funktionalität, die ein Objekt (über Funktionen dieser Schnittstelle) ausführen kann, und Abstract Class repräsentiert a übergeordnetes Element einer Hierarchie, um untergeordnete Elemente mit der Kernstruktur (Eigenschaft + Funktionalität) des übergeordneten Elements zu erzeugen

Wenn Sie nach dem Unterschied gefragt werden, handelt es sich tatsächlich um einen konzeptionellen Unterschied, nicht um den Unterschied bei der sprachspezifischen Implementierung, es sei denn, Sie werden ausdrücklich dazu aufgefordert. 

Ich glaube, beide Interviewer erwarteten einen klaren Unterschied zwischen diesen beiden, und als Sie versagten, haben Sie versucht, Sie auf diesen Unterschied zu bringen, indem Sie ONE als ANDERE implementierten

Was wäre, wenn Sie eine abstrakte Klasse mit nur abstrakten Methoden hätten?

24
bjan

Für .Net, 

Ihre Antwort auf Der zweite Interviewer ist auch die Antwort auf den ersten ... Abstrakte Klassen können Implementierung und Status haben, Schnittstellen können nicht ... 

BEARBEITEN: In einem anderen Hinweis würde ich nicht einmal den Ausdruck "Unterklasse" (oder den Satz "Vererbung") verwenden, um Klassen zu beschreiben, die "definiert sind, um eine Schnittstelle zu implementieren". Für mich ist eine Schnittstelle eine Definition eines Vertrages, dem eine Klasse entsprechen muss, wenn sie definiert wurde, um diese Schnittstelle zu "implementieren". Es erbt nichts ... Sie müssen alles selbst hinzufügen, explizit. 

21
Charles Bretana

Ich denke, sie haben Ihre Antwort nicht gemocht, weil Sie die technischen Unterschiede anstelle der konstruktiven Unterschiede angegeben haben. Die Frage ist für mich wie eine Trollfrage. In der Tat haben Schnittstellen und abstrakte Klassen einen völlig anderen Charakter, so dass 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.

interface: wird verwendet, um einen Vertrag sicherzustellen und eine geringe Kopplung zwischen Klassen herzustellen, um eine wartungsfähigere, skalierbarere und testbare Anwendung zu erhalten.

abstract class: wird nur verwendet, um Code zwischen Klassen derselben Verantwortung 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 (stattdessen composition ).

Schnittstellen haben also eine echte architektonische Rolle, während abstrakte Klassen fast nur ein Implementierungsdetail sind (wenn Sie es natürlich korrekt verwenden).

17
Gnucki

Interface: sollte verwendet werden, wenn Sie eine Regel für die Komponenten festlegen möchten, die sich auf Beziehen können oder nicht

Pros:

  1. Erlaubt mehrfache Vererbung
  2. Stellt Abstraktion bereit, indem nicht offenbart wird, welche Art von Objekt im Kontext verwendet wird
  3. sorgt für Konsistenz durch eine spezifische Vertragsunterzeichnung

Nachteile:

  1. Alle definierten Verträge müssen umgesetzt werden
  2. Kann keine Variablen oder Delegaten haben
  3. Einmal definiert kann nicht geändert werden, ohne alle Klassen zu brechen

Abstract Class: sollte verwendet werden, wenn grundlegende oder standardmäßige Verhaltensweisen oder Implementierungen für miteinander verwandte Komponenten erforderlich sind

Pros:

  1. Schneller als die Schnittstelle
  2. Hat Flexibilität in der Implementierung (Sie können sie vollständig oder teilweise implementieren)
  3. Kann leicht geändert werden, ohne die abgeleiteten Klassen zu brechen

Nachteile:

  1. Kann nicht instanziiert werden
  2. Unterstützt keine Mehrfachvererbung
14
After all that, the interviewer came up with the question "What if you had an 
Abstract class with only abstract methods? How would that be different
from an interface?" 

Docs sagen eindeutig, wenn eine abstrakte Klasse nur abstrakte Methodendeklarationen enthält, sollte sie stattdessen als Schnittstelle deklariert werden.

An another interviewer asked me what if you had a Public variable inside
the interface, how would that be different than in Abstract Class?

Variablen in Schnittstellen sind standardmäßig public static und final. Die Frage könnte wie dargestellt werden, 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.

Zum Schluss möchte ich noch einen Punkt hinzufügen - abstrakte Klassen sind immer noch Klassen und fallen in einen einzigen Vererbungsbaum, wohingegen Schnittstellen in Mehrfachvererbung vorhanden sein können.

13
Aniket Thakur
  1. Schnittstelle:
    • Wir implementieren (oder definieren) keine Methoden, wir machen das in abgeleiteten Klassen.
    • Wir deklarieren keine Member-Variablen in Interfaces.
    • Schnittstellen drücken die HAS-A-Beziehung aus. Das heißt, sie sind eine Maske von Objekten.
  2. Abstrakte Klasse:
    • Wir können Methoden in abstrakten Klassen deklarieren und definieren.
    • Wir verstecken Konstrukteure davon. Das heißt, es wird kein Objekt direkt daraus erstellt.
    • Eine abstrakte Klasse kann Elementvariablen enthalten.
    • Abgeleitete Klassen erben eine abstrakte Klasse, die bedeutet, dass Objekte aus abgeleiteten Klassen nicht maskiert werden, sie erben eine abstrakte Klasse. Die Beziehung ist in diesem Fall IS-A.

Das ist meine Meinung.

12
nautilusvn

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:

■■ IS-A vs. CAN-DO-Beziehung Ein Typ kann nur eine Implementierung erben. Wenn der abgeleitete Typ keine IS-A-Beziehung mit dem Basistyp beanspruchen kann, verwenden Sie keinen Basistyp. Verwenden Sie eine Schnittstelle . Schnittstellen setzen eine CAN-DO-Beziehung voraus. Wenn die CAN-DO-Funktionalität mit verschiedenen Objekttypen zu gehören scheint, verwenden Sie eine Schnittstelle. Ein Typ kann zum Beispiel Instanzen von sich selbst konvertieren. __ in einen anderen Typ (IConvertible), ein Typ kann eine Instanz von sich selbst (ISerializable), Etc. Serialisieren. Beachten Sie, dass Werttypen von System.ValueType abgeleitet sein müssen und daher nicht von einer beliebigen Basisklasse abgeleitet werden können. In diesem Fall müssen Sie eine CAN-DO-Beziehung Verwenden und eine Schnittstelle definieren.

Einfache Anwendung Als Entwickler ist es normalerweise einfacher, einen neuen Typ zu definieren, der von einem Basistyp .__ abgeleitet ist, als alle Methoden einer Schnittstelle zu implementieren. Der Basistyp kann eine große Anzahl von Funktionen bereitstellen, so dass der abgeleitete Typ wahrscheinlich nur relativ kleine Änderungen an seinem Verhalten erfordert. Wenn Sie eine Schnittstelle angeben, muss der neue Typ alle Member implementieren.

■■ Konsequente Implementierung Unabhängig davon, wie gut ein Schnittstellenvertrag dokumentiert wird, ist es sehr unwahrscheinlich, dass jeder den Vertrag zu 100 Prozent korrekt umsetzt. In der Tat leidet COM Unter genau diesem Problem, weshalb einige COM-Objekte nur mit Microsoft Word oder mit Windows Internet Explorer ordnungsgemäß funktionieren. Durch die Bereitstellung eines Basistyps mit einer guten -Standardimplementierung beginnen Sie mit einem 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 starten mit einem funktionierenden Typ, und der Quellcode des Benutzers muss nicht einmal neu kompiliert werden. Das Hinzufügen eines neuen Elements zu einer Schnittstelle zwingt den Vererber der Schnittstelle, den Quellcode zu ändern und den Quellcode neu zu kompilieren.

12
Deepak Mishra

Eine Schnittstelle definiert einen Vertrag für einen Service oder eine Gruppe von Services. Sie sorgen auf horizontale Weise für Polymorphismus, indem zwei vollständig voneinander unabhängige Klassen dieselbe Schnittstelle implementieren, jedoch als Parameter des von ihnen implementierten Schnittstellentyps austauschbar verwendet werden, da beide Klassen versprochen haben, die durch die Schnittstelle definierten Dienste zu erfüllen. Schnittstellen liefern keine Implementierungsdetails.

Eine abstrakte Klasse definiert eine Basisstruktur für ihre Unterklassen und optional eine teilweise Implementierung. Abstrakte Klassen stellen Polymorphismus auf vertikale, aber gerichtete Weise bereit, indem jede Klasse, die die abstrakte Klasse erbt, als Instanz dieser abstrakten Klasse behandelt werden kann, jedoch nicht umgekehrt. Abstrakte Klassen können und enthalten oft Implementierungsdetails, können jedoch nicht selbst instanziiert werden - nur ihre Unterklassen können "neu angelegt" werden.

In C # ist jedoch auch die Vererbung von Schnittstellen möglich.

10
joelmdev

Da Sie vielleicht das theoretische Wissen von Experten erhalten haben, gebe ich nicht viele Worte, um alle hier zu wiederholen, sondern lassen Sie mich mit einem einfachen Beispiel erklären, wo wir Interface und Abstract class verwenden können/können.

Stellen Sie sich vor, Sie entwerfen eine Anwendung, um alle Funktionen von Autos aufzulisten. An verschiedenen Stellen ist eine gemeinsame Vererbung erforderlich, da einige Eigenschaften wie DigitalFuelMeter, Klimaanlage, Sitzverstellung usw. für alle Fahrzeuge üblich sind. Ebenso benötigen wir nur für einige Klassen die Vererbung, da einige Eigenschaften wie das Bremssystem (ABS, EBD) nur für einige Fahrzeuge gelten. 

Die untere Klasse dient als Basisklasse für alle Autos:

public class Cars
{
    public string DigitalFuelMeter()
    {
        return "I have DigitalFuelMeter";
    }

    public string AirCondition()
    {
        return "I have AC";
    }

    public string SeatAdjust()
    {
        return "I can Adjust seat";
    }
}

Stellen Sie sich vor, wir haben für jedes Auto eine eigene Klasse.

public class Alto : Cars
{
    // Have all the features of Car class    
}

public class Verna : Cars
{
    // Have all the features of Car class + Car need to inherit ABS as the Braking technology feature which is not in Cars        
}

public class Cruze : Cars
{
    // Have all the features of Car class + Car need to inherit EBD as the Braking technology feature which is not in Cars        
}

Stellen Sie sich vor, wir benötigen eine Methode zum Erben der Bremstechnologie für die Autos Verna und Cruze (nicht für Alto). Obwohl beide Bremstechniken verwenden, unterscheidet sich die "Technologie". Wir erstellen also eine abstrakte Klasse, in der die Methode als Abstract deklariert wird und in ihren Kindklassen implementiert werden sollte.

public abstract class Brake
{
    public abstract string GetBrakeTechnology();
}

Nun versuchen wir, von dieser abstrakten Klasse zu erben, und die Art des Bremssystems ist in Verna und Cruze implementiert:

public class Verna : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }       
}

public class Cruze : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
       return "I use EBD system for braking";
    }         
}

Sehen Sie das Problem in den beiden obigen Klassen? Sie erben von mehreren Klassen, die C # .Net nicht zulässt, obwohl die Methode in den untergeordneten Elementen implementiert ist. Hier kommt das Bedürfnis nach Schnittstelle.

interface IBrakeTechnology
{
    string GetBrakeTechnology();
}

Und die Implementierung ist unten angegeben:

public class Verna : Cars, IBrakeTechnology
{
    public string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }
}

public class Cruze : Cars, IBrakeTechnology
{
   public string GetBrakeTechnology()
   {
       return "I use EBD system for braking";
   }        
}

Nun können Verna und Cruze mit Hilfe von Interface mehrere Vererbungen mit eigenen Bremstechniken erreichen.

10
Sarath Avanavu

Die meisten Antworten konzentrieren sich auf den technischen Unterschied zwischen abstrakter Klasse und Schnittstelle, aber da technisch gesehen eine Schnittstelle im Grunde eine Art abstrakter Klasse ist (eine ohne Daten oder Implementierung), denke ich, dass der konzeptuelle Unterschied ist viel interessanter, und das ist vielleicht das, wonach die Interviewer streben.

Ein Interface ist ein Vereinbarung. Darin heißt es: "So reden wir miteinander". Es kann keine Implementierung geben, da keine Implementierung hat. Es ist ein Vertrag. Es ist wie die .h-Header-Dateien in C.

Ein Abstract Class ist ein 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 irgendwie nutzlos, aber völlig legal.

Grundsätzlich geht es bei jeder Klasse, ob abstrakt oder nicht, darum, was ist, wohingegen es sich bei einer Schnittstelle um handelt, wie Sie sie verwenden. Zum Beispiel: Animal könnte eine abstrakte Klasse sein, die einige grundlegende metabolische Funktionen implementiert und abstrakte Methoden für die 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 könnte andererseits eine Schnittstelle sein, die angibt, dass Sie mit dem Tier fahren 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 nehmen sie völlig unterschiedliche Rollen ein.

10
mcv

Schnittstellen sind ein leichter Weg, um ein bestimmtes Verhalten durchzusetzen. Das ist eine Möglichkeit, darüber nachzudenken.

9
fastcodejava

Schnittstellentypen vs. abstrakte Basisklassen

Angepasst aus dem Pro C # 5.0 und dem .NET 4.5 Framework book.

Der Schnittstellentyp scheint einer abstrakten Basisklasse sehr ähnlich zu sein. Es sei daran erinnert, dass .__ wenn eine Klasse als abstrakt markiert ist, sie eine beliebige Anzahl abstrakter Elemente definieren kann, um eine polymorphe Schnittstelle für alle abgeleiteten Typen bereitzustellen. Selbst wenn eine Klasse eine Gruppe von abstrakten .__-Elementen definiert, können Sie jedoch beliebig viele Konstruktoren, Felddaten, nicht abstrakte Elemente (mit Implementierung) usw. definieren. Schnittstellen enthalten dagegen nur abstrakte Elementdefinitionen .. Die polymorphe Schnittstelle, die von einer abstrakten übergeordneten Klasse erstellt wird, unterliegt einer wesentlichen Einschränkungin, dass nur abgeleitete Typen die vom abstrakten übergeordneten Element definierten Elemente unterstützen. In größeren Software-Systemen ist es jedoch üblich, mehrere Klassenhierarchien zu entwickeln, die kein gemeinsames übergeordnetes System außerhalb von System.Object haben. Da abstrakte Elemente in einer abstrakten Basisklasse nur für abgeleitete Typen gelten, haben wir keine Möglichkeit, Typen in verschiedenen Hierarchien so zu konfigurieren, dass sie dieselbe polymorphe Schnittstelle unterstützen. Angenommen, Sie haben die folgende abstrakte Klasse definiert:

public abstract class CloneableType
{
// Only derived types can support this
// "polymorphic interface." Classes in other
// hierarchies have no access to this abstract
// member.
   public abstract object Clone();
}

Bei dieser Definition können nur Mitglieder, die CloneableType erweitern, die Methode Clone () Unterstützen. Wenn Sie eine neue Gruppe von Klassen erstellen, die diese Basisklasse nicht erweitern, können Sie diese polymorphe Schnittstelle (_) nicht erhalten. Möglicherweise erinnern Sie sich auch daran, dass C # keine Mehrfachvererbung für Klassen unterstützt. Wenn Sie also einen MiniVan erstellen möchten, der ein Auto und ein CloneableType ist, können Sie dies nicht tun:

// Nope! Multiple inheritance is not possible in C#
// for classes.
public class MiniVan : Car, CloneableType
{
}

Wie Sie sich vorstellen können, kommen Schnittstellentypen zur Rettung. Nachdem eine Schnittstelle definiert wurde, kann sie von einer beliebigen Klasse oder Struktur in einer beliebigen Hierarchie in einem beliebigen Namespace oder einer beliebigen Assembly (in einer beliebigen .NET-Programmiersprache) implementiert werden. Wie Sie sehen können, sind Schnittstellen sehr polymorph ... _. Betrachten Sie die .NET-Standardschnittstelle namens ICloneable, die im System-Namespace definiert ist. Diese Schnittstelle definiert eine einzelne Methode namens Clone ():

public interface ICloneable
{
object Clone();
}
6
Jahan

Beantworten Sie die zweite Frage: public in interface definierte Variable ist standardmäßig static final, während die Variable public in abstract-Klasse eine Instanzvariable ist.

6
Nidhi Agarwal

1) Eine Schnittstelle kann als reine abstrakte Klasse betrachtet werden, ist dieselbe, jedoch ist sie nicht das Gleiche, um eine Schnittstelle zu implementieren und von einer abstrakten Klasse zu erben. Wenn Sie von dieser rein abstrakten Klasse erben, definieren Sie eine Hierarchie -> Vererbung. Wenn Sie die Schnittstelle implementieren, sind Sie nicht in der Lage, und Sie können beliebig viele Schnittstellen implementieren. Sie können jedoch nur von einer Klasse erben.

2) Sie können eine Eigenschaft in einer Schnittstelle definieren. Die Klasse, die diese Schnittstelle implementiert, muss diese Eigenschaft besitzen.

Zum Beispiel:

  public interface IVariable
  {
      string name {get; set;}
  }

Die Klasse, die diese Schnittstelle implementiert, muss eine solche Eigenschaft haben.

6
MRFerocius

Obwohl diese Frage ziemlich alt ist, möchte ich noch einen Punkt für Schnittstellen hinzufügen: 

Schnittstellen können mit beliebigen Abhängigkeitseinspritzungswerkzeugen injiziert werden, wobei die abstrakte Klasseninjektion von sehr wenigen unterstützt wird.

6
paragy

Von eine andere Antwort von mir , die sich hauptsächlich damit beschäftigt, wann man eins gegen das andere verwendet:

Schnittstellen sind meiner Erfahrung nach am besten Wird verwendet, wenn Sie mehrere Klassen haben die jeweils auf dasselbe reagieren müssen Methode oder Methoden, damit sie .__ sein können. wird durch anderen Code austauschbar verwendet das wird gegen jene geschrieben werden allgemeine Schnittstelle der Klassen. Das beste Verwendung einer Schnittstelle ist, wenn die Protokoll ist wichtig, aber das zugrundeliegende Logik kann für .__ unterschiedlich sein. jede Klasse. Wenn Sie sonst wären Duplizierlogik, betrachten Sie abstrakt Klassen oder Vererbung von Standardklassen stattdessen.

5
Adam Alexander

Aus der Perspektive der Codierung

Eine Schnittstelle kann eine abstrakte Klasse ersetzen, wenn die abstrakte Klasse nur abstrakte Methoden enthält. Andernfalls wird das Ändern der abstrakten Klasse in eine Schnittstelle dazu führen, dass Sie die Wiederverwendbarkeit von Code durch Inheritance verlieren.

Aus Designperspektive

Behalten Sie es als abstrakte Klasse, wenn es sich um eine "Ist-Beziehung" handelt und Sie eine Untermenge oder die gesamte Funktionalität benötigen. Behalten Sie es als Schnittstelle bei, wenn es sich um eine "Soll-Beziehung" handelt.

Entscheiden Sie, was Sie benötigen: nur die Durchsetzung von Richtlinien oder Wiederverwendbarkeit UND Code von Code.

4
Vivek Vermani

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 Befehl if nicht genau als die Bedeutung des Begriffs funktioniert? Außerdem verringern einige Sprachen sogar die Unterschiede zwischen einer Schnittstelle und einer Zusammenfassung. Wenn die beiden Begriffe eines Tages zufällig fast identisch funktionieren, können Sie sich zumindest definieren, wo (und warum) eine der Sprachen sein sollte 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 allgemeine Definitionen. Ich denke, diese beiden Bedeutungen, die ich in diese Seite gefunden habe, sind wirklich sehr gut und passend.

Schnittstelle: 

Eine Sache oder ein Umstand, durch den separate und manchmal inkompatible Elemente effektiv koordiniert werden können.

Abstrakt: 

Etwas, das die wesentlichen Eigenschaften von etwas weiterem oder allgemeinerem oder von mehreren Dingen in sich konzentriert; Wesen. 

Beispiel: 

Sie haben ein Auto gekauft und es braucht Kraftstoff. 

enter image description here

Ihr Automodell ist XYZ, was dem Genre ABC entspricht, also ist es ein konkretes Auto, eine bestimmte Instanz eines Autos. Ein Auto ist kein echtes Objekt. In der Tat ist es eine abstrakte Menge von Standards (Qualitäten), um ein bestimmtes Objekt zu erstellen. Kurz gesagt, ist Auto ein abstrakte Klasse, es ist "etwas, das die wesentlichen Qualitäten von etwas weiterem oder allgemeinerem in sich konzentriert"

Der einzige Kraftstoff, der mit den Spezifikationen für das Fahrzeughandbuch übereinstimmt, sollte zum Befüllen des Fahrzeugtanks verwendet werden. In der Realität gibt es nichts, was Sie einschränken kann, aber der Motor funktioniert nur mit dem angegebenen Kraftstoff. Daher ist es besser, die Anforderungen zu beachten. Die Anforderungen besagen, dass es als andere Fahrzeuge desselben Genres ABC einen Standard-Kraftstoffsatz akzeptiert.

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 eines Autos gibt. Ihr Fahrzeug könnte zwar einen abstrakten Kraftstoff oder einen VehicularFuel akzeptieren, Sie müssen jedoch daran denken, dass nur ein Teil des vorhandenen Fahrzeugkraftstoffs den Spezifikationen entspricht, die die Anforderungen in Ihrem Fahrzeughandbuch erfüllen. Kurz gesagt, sie sollten das implementieren schnittstelle ABCGenreFuel, welche "... ermöglicht es, dass einzelne und manchmal inkompatible Elemente effektiv koordiniert werden"

Nachtrag

Darüber hinaus denke ich, sollten Sie die Bedeutung des Begriffs "Klasse" berücksichtigen, die (von der gleichen Site, die zuvor erwähnt wurde) ist:

Klasse:

Eine Anzahl von Personen oder Dingen, die aufgrund gemeinsamer Merkmale, Merkmale, Eigenschaften oder Merkmale als Gruppe betrachtet werden; nett;

Auf diese Weise sollte eine Klasse (oder abstrakte Klasse) nicht nur allgemeine Attribute (wie ein Interface) 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. Kinder sollten sich nicht so oft ändern. 

4
Felypp Oliveira

Interface:- == contract.Welche Klasse implementiert, muss sie die gesamte Spezifikation der Schnittstelle befolgen.

Ein Echtzeit-Beispiel wäre jedes mit ISO markierte Produkt. ISO gibt eine Reihe von rules/specification an, wie das Produkt aufgebaut werden soll und welchen minimum set of features es Must hat .

Dies ist nichts anderes als subset of properties product Must have.ISO signiert das Produkt only if it satisfies the its standards.

Schauen Sie sich jetzt diesen Code an

public interface IClock{       //defines a minimum set of specification which a clock should have

    public abstract Date getTime();
    public abstract int getDate();
}
public class Fasttrack: Clock {
    // Must have getTime() and getTime() as it implements IClock
    // It also can have other set of feature like 
    public void startBackgroundLight() {
        // watch with internal light in it.
    }
    .... //Fastrack can support other feature as well
    ....
    ....
}

Hier wird ein Fastrack als Uhr bezeichnet, weil it has all that features that a watch must suppost (Minimum set of features).

Warum und wann abstrakt:

Von MSDN:

Der Zweck eines abstract class besteht darin, einen common definition of a base class bereitzustellen, den mehrere abgeleitete Klassen gemeinsam nutzen können.

Beispielsweise kann eine Klassenbibliothek eine abstrakte Klasse definieren, die als Parameter für viele ihrer Funktionen verwendet wird, und von Programmierern verlangen, dass sie diese Bibliothek verwenden, um ihre eigene Implementierung der Klasse bereitzustellen, indem sie eine abgeleitete Klasse erstellen. Abstract simply means if you cannot define it completely declare it as an abstract. Die Implementierung der Klasse vervollständigt diese Implementierung.

ZB -: Angenommen, ich deklariere eine Klasse Recipe als abstrakt, aber ich weiß nicht, welches Rezept erstellt werden soll. Dann verallgemeinere ich diese Klasse, um den common definition of any recipe zu definieren. Die Implantation des Rezepts wird davon abhängen auf dem Teller implementieren.

Die abstrakte Klasse kann sowohl aus abstrakten als auch aus nicht abstrakten Methoden bestehen. Sie können also den Unterschied in Interface feststellen. Sie müssen also nicht unbedingt alle Methoden Ihrer implementierenden Klasse verwenden. Sie müssen nur die abstrakten Methoden überschreiben.

In einfachen Worten Wenn Sie tight coupling use Interface o/w use in case of lose coupling Abstract Class wollen

3
Dipak Ingole

Einige andere Unterschiede:

Abstrakte Klassen können statische Methoden, Eigenschaften, Felder usw. und Operatoren haben, Schnittstellen können nicht .. Der Cast-Operator ermöglicht das Casting zu/von abstrakten Klassen, nicht aber das Casting an/von Interface.

So ziemlich können Sie abstrakte Klasse selbst verwenden, selbst wenn sie niemals implementiert wird (durch ihre statischen Member) und Sie können die Schnittstelle in keiner Weise alleine verwenden.

3
Orlin Petrov

Die abstrakte Klasse befasst sich mit dem effizienten Packen der Klassenfunktionalität, während die Schnittstelle Absicht/Vertrag/Kommunikation ist und mit anderen Klassen/Modulen gemeinsam genutzt werden soll. 

Die Verwendung abstrakter Klassen als Vertrags- und (Teil-) Vertragsimplementierer verstößt gegen SRP. Die Verwendung einer abstrakten Klasse als Vertrag (Abhängigkeit) beschränkt die Erstellung mehrerer abstrakter Klassen für eine bessere Wiederverwendbarkeit. 

Im Beispiel unten würde die Verwendung der abstrakten Klasse als Vertrag mit OrderManager Probleme verursachen, da wir zwei verschiedene Arten der Auftragsabwicklung haben - je nach Art und Kategorie des Kunden (Kunde kann entweder direkt oder indirekt oder Gold oder Silber sein). Daher wird die Schnittstelle für den Vertrag und die abstrakte Klasse für die Durchsetzung verschiedener Workflows verwendet

public interface IOrderProcessor
{
    bool Process(string orderNumber);
}

public abstract class CustomerTypeOrderProcessor: IOrderProcessor
{
    public bool Process(string orderNumber) => IsValid(orderNumber) ? ProcessOrder(orderNumber) : false;

    protected abstract bool ProcessOrder(string orderNumber);

    protected abstract bool IsValid(string orderNumber);
}

public class DirectCustomerOrderProcessor : CustomerTypeOrderProcessor
{
    protected override bool IsValid(string orderNumber) => string.IsNullOrEmpty(orderNumber); 

    protected override bool ProcessOrder(string orderNumber) => true; 
}

public class InDirectCustomerOrderProcessor : CustomerTypeOrderProcessor
{
    protected override bool IsValid(string orderNumber) => orderNumber.StartsWith("EX");

    protected override bool ProcessOrder(string orderNumber) => true;
}

public abstract class CustomerCategoryOrderProcessor : IOrderProcessor
{
    public bool Process(string orderNumber) => ProcessOrder(GetDiscountPercentile(orderNumber), orderNumber);

    protected abstract int GetDiscountPercentile(string orderNumber);

    protected abstract bool ProcessOrder(int discount, string orderNumber);
}

public class GoldCustomer : CustomerCategoryOrderProcessor
{
    protected override int GetDiscountPercentile(string orderNumber) => 15;

    protected override bool ProcessOrder(int discount, string orderNumber) => true;

}

public class SilverCustomer : CustomerCategoryOrderProcessor
{
    protected override int GetDiscountPercentile(string orderNumber) => 10;

    protected override bool ProcessOrder(int discount, string orderNumber) => true;

}

public class OrderManager
{
    private readonly IOrderProcessor _orderProcessor;// Not CustomerTypeOrderProcessor or CustomerCategoryOrderProcessor 

    //Using abstract class here would create problem as we have two different abstract classes
    public OrderManager(IOrderProcessor orderProcessor) => _orderProcessor = orderProcessor;
}
1
Saravanan

Außer für den Vergleich von Abstract class mit Interface ist es sinnvoll, Abstract class mit Concrete class zu vergleichen. 

Verwenden Sie abstrakte Klassen, während Sie konkrete Klassen verwenden, nur mit Ausnahme von der Zeiten, zu denen Sie nicht wollen/können, sie nicht instanziieren können, ohne erweitert zu werden. Und machen Sie die Methoden, die Sie nicht wollen/können, um abstrakte Methoden zu implementieren. 

Wenn Sie Analogie mögen, denken Sie an Chrom als abstrakte Klasse (Sie können es nicht als Browser verwenden, damit es nicht instanziiert werden kann), Chrom und Oper als konkrete, von Chrom abgeleitete Klassen und Browser-Add-On-Struktur als Schnittstelle.

Schnittstelle:

Enthält keine Impleamentierungen Die Schnittstelle kann von mehreren Schnittstellen erben (Mehrfachvererbung wird unterstützt) Mitglieder sind automatisch öffentlich Kann Eigenschaften, Methoden, Ereignisse und Indexer enthalten

Abstrakte Klasse:

Kann/darf keine Implementierungen enthalten; Mindestens ein Mitglied wird nicht implementiert. Eine Klasse kann von einer einzelnen Basisklasse erben. Mehrfachvererbung nicht zulässig . Mitglieder haben Zugriffsmodifizierer Kann Felder, Eigenschaften, Konstruktoren, Destruktoren, Methoden, Ereignisse und Indexer enthalten

Dies sind die Hauptunterschiede zwischen abstrakten Klassen und Schnittstellen.

0
Vishwas S L

Diese Antworten sind viel zu lang.

  • Schnittstellen dienen zur Definition von Verhaltensweisen.

  • Abstrakte Klassen dienen dazu, ein Objekt 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. Denn ein konkretes Objekt kann nicht verschiedene Dinge sein, sondern es kann unterschiedliche Verhaltensweisen haben.

0
K.Miao