Was ist der Unterschied zwischen einer Schnittstelle und einer abstrakten Klasse?

1753

Was genau ist der Unterschied zwischen einer Schnittstelle und einer abstrakten Klasse?

Sarfraz
quelle
96
Dies ist eine äußerst häufige Interviewfrage. Es ist überraschend, da eine abstrakte Klasse in Lösungen im Vergleich zu anderen Dingen selten verwendet wird. Ihre Frage hat mir geholfen, Safraz.
Catto
5
Diese Frage könnte auch helfen, das Konzept der Schnittstellen zu verstehen stackoverflow.com/q/8531292/1055241
gprathour
6
Ich habe das PHP-Tag aus dieser Frage entfernt, da fast keine der Antworten sprachspezifisch ist und die Frage selbst nicht sprachspezifisch ist.
Brice
2
Früher war eine Schnittstelle in c ++ eine reine abstrakte Basisklasse mit allen Methodenimplementierungen = 0. Wenn eine einzelne Methode nicht = 0 war, hat sie eine Implementierung und die abstrakte Basis ist nicht mehr rein und keine Schnittstelle mehr . Ich denke, die VMT hat weniger Indirektion, wenn die Mehrfachvererbung nur reine abstrakte Basen verwendet, aber ich erinnere mich nicht mehr, wie sie aussehen, zu lange.
Jim

Antworten:

2255

Schnittstellen

Eine Schnittstelle ist ein Vertrag : Die Person, die die Schnittstelle schreibt, sagt: " Hey, ich akzeptiere Dinge, die so aussehen ", und die Person, die die Schnittstelle verwendet, sagt " OK, die Klasse, die ich schreibe, sieht so aus ".

Eine Schnittstelle ist eine leere Shell . Es gibt nur die Signaturen der Methoden, was bedeutet, dass die Methoden keinen Körper haben. Die Schnittstelle kann nichts tun. Es ist nur ein Muster.

Zum Beispiel (Pseudocode):

// I say all motor vehicles should look like this:
interface MotorVehicle
{
    void run();

    int getFuel();
}

// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{

    int fuel;

    void run()
    {
        print("Wrroooooooom");
    }


    int getFuel()
    {
        return this.fuel;
    }
}

Das Implementieren einer Schnittstelle verbraucht sehr wenig CPU, da es sich nicht um eine Klasse, sondern nur um eine Reihe von Namen handelt und daher keine teure Suche erforderlich ist. Es ist großartig, wenn es darauf ankommt, beispielsweise bei eingebetteten Geräten.


Abstrakte Klassen

Abstrakte Klassen sind im Gegensatz zu Schnittstellen Klassen. Ihre Verwendung ist teurer, da beim Nacherben von ihnen nachgeschlagen werden muss.

Abstrakte Klassen sehen Schnittstellen sehr ähnlich, haben aber noch etwas mehr: Sie können ein Verhalten für sie definieren. Es geht eher um eine Person, die sagt: " Diese Klassen sollten so aussehen, und sie haben das gemeinsam, also füllen Sie die Lücken aus! ".

Zum Beispiel:

// I say all motor vehicles should look like this:
abstract class MotorVehicle
{

    int fuel;

    // They ALL have fuel, so lets implement this for everybody.
    int getFuel()
    {
         return this.fuel;
    }

    // That can be very different, force them to provide their
    // own implementation.
    abstract void run();
}

// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
    void run()
    {
        print("Wrroooooooom");
    }
}

Implementierung

Während abstrakte Klassen und Schnittstellen unterschiedliche Konzepte sein sollen, machen die Implementierungen diese Aussage manchmal unwahr. Manchmal sind sie nicht einmal das, was Sie denken.

In Java wird diese Regel stark durchgesetzt, während in PHP Schnittstellen abstrakte Klassen ohne deklarierte Methode sind.

In Python sind abstrakte Klassen eher ein Programmiertrick, den Sie vom ABC-Modul erhalten können, und verwenden tatsächlich Metaklassen und damit Klassen. Und Schnittstellen beziehen sich eher auf die Eingabe von Enten in dieser Sprache und es ist eine Mischung aus Konventionen und speziellen Methoden, die Deskriptoren aufrufen (die __method__-Methoden).

Wie beim Programmieren üblich, gibt es Theorie, Praxis und Praxis in einer anderen Sprache :-)

e-satis
quelle
6
Der entscheidende Punkt bei Schnittstellen ist nicht so sehr, dass sie sagen, was eine Klasse tut, sondern dass Objekte, die Wizzle können, sich für Code nützlich machen, der einen Wizzler benötigt. Beachten Sie, dass in vielen Fällen weder die Person, die das schreibt, was Wizzle kann, noch die Person, die einen Wizzler benötigt, die Person ist, die die Benutzeroberfläche schreibt.
Supercat
187
Ich denke nicht, dass der CPU-Verbrauch der hervorstechende Punkt bei Schnittstellen ist.
Dan Lugg
5
@ e-satis Können Sie bitte Ihren Standpunkt zur CPU-Auslastung erläutern? Warum erhöht eine abstrakte Klasse als Klasse die CPU-Auslastung? Auf welche Art von Suche beziehen Sie sich hier?
Geek
36
@ e-satis Mit Java 8 können Sie Standardmethoden in Schnittstellen definieren, was nicht abstrakten Methoden in abstrakten Klassen entspricht. Mit diesem Zusatz kann ich den wirklichen Unterschied zwischen abstrakten Klassen und Schnittstelle nicht mehr erkennen, abgesehen von der Tatsache, dass ich Schnittstellen verwenden sollte, da Klassen mehrere Schnittstellen implementieren können, aber nur eine Klasse erben können
Ogen
23
Ich denke, der Vergleich zwischen interfaceund classvon Head First Javaist lebendig, dassA class defines who you are, and an interface tells what roles you could play
LittleLittleQ
872

Die wichtigsten technischen Unterschiede zwischen einer abstrakten Klasse und einer Schnittstelle sind:

  • Abstrakte Klassen können Konstanten, Mitglieder, Methodenstubs (Methoden ohne Body) und definierte Methoden haben , während Schnittstellen nur Konstanten und Methodenstubs haben können .

  • Methoden und Mitglieder einer abstrakten Klasse können mit jeder Sichtbarkeit definiert werden , während alle Methoden einer Schnittstelle als definiert werden müssen public(sie sind standardmäßig öffentlich definiert).

  • Beim Erben einer abstrakten Klasse muss eine konkrete untergeordnete Klasse die abstrakten Methoden definieren , während eine abstrakte Klasse eine andere abstrakte Klasse erweitern kann und abstrakte Methoden aus der übergeordneten Klasse nicht definiert werden müssen.

  • In ähnlicher Weise ist eine Schnittstelle, die eine andere Schnittstelle erweitert, nicht für die Implementierung von Methoden von der übergeordneten Schnittstelle verantwortlich. Dies liegt daran, dass Schnittstellen keine Implementierung definieren können.

  • Eine untergeordnete Klasse kann nur eine einzelne Klasse (abstrakt oder konkret) erweitern, während eine Schnittstelle erweitert werden kann oder eine Klasse mehrere andere Schnittstellen implementieren kann .

  • Eine untergeordnete Klasse kann abstrakte Methoden mit derselben oder einer weniger restriktiven Sichtbarkeit definieren , während eine Klasse, die eine Schnittstelle implementiert, die Methoden mit genau derselben Sichtbarkeit (öffentlich) definieren muss.

Justin Johnson
quelle
123
Ich denke, dies ist die beste Antwort, da sie alle wichtigen Unterschiede hervorhebt. Ein Beispiel ist nicht wirklich notwendig.
Joshua K
4
Und normalerweise können Sie mit Klassen ein Objekt daraus instanziieren, im Gegensatz zu den abstrakten Klassen, die CANNOTinstanziiert werden.
SASM
Ich dachte, eine Klasse, die die Schnittstelle implementiert, muss alle Methoden in der Schnittstelle definieren?
Jiazzy Benutzer
@Jiazzyuser Wenn eine abstrakte Klasse eine Schnittstelle implementiert, muss sie die Methoden der Schnittstelle nicht definieren. Diese Anforderung kann auf erbende / untergeordnete konkrete Klassen verschoben werden. Eine konkrete Klasse muss jedoch alle Schnittstellenmethoden implementieren, die nicht von ihrer übergeordneten Klasse implementiert werden. Ich werde ein Beispiel hinzufügen, um diesen Punkt zu veranschaulichen.
Justin Johnson
5
"Beim Erben einer abstrakten Klasse muss die untergeordnete Klasse die abstrakten Methoden definieren, während eine Schnittstelle eine andere Schnittstelle erweitern kann und Methoden nicht definiert werden müssen." - Das ist nicht wahr. So wie eine Schnittstelle eine Schnittstelle erweitern kann, ohne Methoden zu definieren, kann eine abstrakte Klasse eine abstrakte Klasse erben, ohne Methoden zu definieren.
Nick
141

Eine Schnittstelle enthält nur die Definition / Signatur der Funktionalität. Wenn wir einige gemeinsame Funktionen sowie gemeinsame Signaturen haben, müssen wir eine abstrakte Klasse verwenden. Durch die Verwendung einer abstrakten Klasse können wir sowohl Verhalten als auch Funktionalität gleichzeitig bereitstellen. Ein anderer Entwickler, der eine abstrakte Klasse erbt, kann diese Funktionalität problemlos verwenden, da nur die Lücken ausgefüllt werden müssen.

Geben Sie hier die Bildbeschreibung ein Genommen von:

http://www.dotnetbull.com/2011/11/difference-between-abstract-class-and.html

http://www.dotnetbull.com/2011/11/what-is-abstract-class-in-c-net.html http://www.dotnetbull.com/2011/11/what-is-interface-in -c-net.html

Vivek
quelle
17
Sie müssen sagen, für welche Sprache dies gilt ("Abstrakte Klasse unterstützt keine Mehrfachvererbung" ist alles andere als allgemein gültig)
Ben Voigt
Letzter Vergleich ist laut Tabelle verwirrend! Methoden in der Schnittstelle können nicht statisch sein, aber Variablen sind statisch final Implementierte Methoden in der abstrakten Klasse können statisch sein
realPK
8
Das Mitglied der Schnittstelle muss statisch final sein. Letzte Aussage ist falsch.
Jawad Zeb
Ich denke, "Funktionalität" in dieser Antwort bedeutet "Implementierung". Nicht sicher, was "Verhalten" bedeutet - vielleicht "Unterschriften"?
LarsH
2
Was ist die angestrebte Programmiersprache hier? C #?
Peter Mortensen
80

Eine Erklärung finden Sie hier: http://www.developer.com/lang/php/article.php/3604111/PHP-5-OOP-Interfaces-Abstract-Classes-and-the-Adapter-Pattern.htm

Eine abstrakte Klasse ist eine Klasse, die vom Programmierer nur teilweise implementiert wird. Es kann eine oder mehrere abstrakte Methoden enthalten. Eine abstrakte Methode ist einfach eine Funktionsdefinition, die dem Programmierer mitteilt, dass die Methode in einer untergeordneten Klasse implementiert werden muss.

Eine Schnittstelle ähnelt einer abstrakten Klasse. In der Tat belegen Schnittstellen denselben Namespace wie Klassen und abstrakte Klassen. Aus diesem Grund können Sie keine Schnittstelle mit demselben Namen wie eine Klasse definieren. Eine Schnittstelle ist eine vollständig abstrakte Klasse. Keine seiner Methoden ist implementiert, und anstelle einer Klassenunterklassifizierung soll diese Schnittstelle implementiert werden.

Jedenfalls finde ich diese Erklärung der Schnittstellen etwas verwirrend. Eine häufigere Definition lautet: Eine Schnittstelle definiert einen Vertrag, den implementierende Klassen erfüllen müssen. Eine Schnittstellendefinition besteht aus Signaturen öffentlicher Mitglieder ohne Implementierungscode.

Konamiman
quelle
4
Dies ist die richtigste Antwort, da sich PHP-Schnittstellen von anderen Sprachen dadurch unterscheiden, dass PHP-Schnittstellen abstrakte Klassen unter der Haube sind, während die Schnittstellen anderer Sprachen Signaturen sind, mit denen Klassen übereinstimmen müssen. Sie verhalten sich genauso, solange keine Fehler vorliegen.
Tor Valamo
1
Es stimmt, für PHP ist es die wirklich beste Antwort. Es ist jedoch schwieriger, aus dem Text-Blob als aus einem einfachen Ausschnitt zu gelangen.
E-Satis
Von den von Ihnen angegebenen Definitionen sehen sie bis auf ein Detail gleich aus: Die Schnittstelle ist zu 100% abstrakt, während eine abstrakte Klasse teilweise abstrakt ist und einige Methodenimplementierungen aufweisen kann (möglicherweise können alle Methoden Implementierungen haben?).
JWW
41

Ich möchte nicht auf die Unterschiede hinweisen, die bereits in vielen Antworten erwähnt wurden (in Bezug auf öffentliche statische Endmodifikatoren für Variablen in der Schnittstelle und Unterstützung für geschützte, private Methoden in abstrakten Klassen).

In einfachen Worten möchte ich sagen:

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

Aus der Oracle- Dokumentation

Verwenden Sie abstrakte Klassen, wenn:

  1. Sie möchten Code für mehrere eng verwandte Klassen freigeben.
  2. Sie erwarten, dass Klassen, die Ihre abstrakte Klasse erweitern, über viele gängige Methoden oder Felder verfügen oder andere als öffentliche (z. B. geschützte und private) Zugriffsmodifikatoren erfordern.
  3. Sie möchten nicht statische oder nicht endgültige Felder deklarieren.

Erwägen Sie die Verwendung von Schnittstellen, wenn:

  1. Sie erwarten, dass nicht verwandte Klassen Ihre Schnittstelle implementieren. Beispielsweise können viele nicht verwandte Objekte eine SerializableSchnittstelle implementieren .
  2. Sie möchten das Verhalten eines bestimmten Datentyps angeben, sind jedoch nicht darüber besorgt, wer sein Verhalten implementiert.
  3. Sie möchten die Mehrfachvererbung des Typs nutzen.

abstrakte Klasse stellt "ist eine" Beziehung zu konkreten Klassen her. Schnittstelle bietet "hat eine" Fähigkeit für Klassen.

Wenn Sie Javaals Programmiersprache suchen , finden Sie hier einige weitere Updates:

Java 8 hat die Lücke zwischen interfaceund abstractKlassen durch die Bereitstellung einer defaultMethodenfunktion in gewissem Maße verringert . Eine Schnittstelle hat keine Implementierung für eine Methode, die jetzt nicht mehr gültig ist.

Siehe diese Dokumentation Seite für weitere Details.

In dieser SE-Frage finden Sie Codebeispiele, um sie besser zu verstehen.

Wie hätte ich den Unterschied zwischen einer Interface- und einer Abstract-Klasse erklären sollen?

Ravindra Babu
quelle
38

Einige wichtige Unterschiede:

In Form einer Tabelle:

Unterschied

Wie von Joe aus Javapapers angegeben :

1. Der Hauptunterschied besteht darin, dass Methoden einer Java-Schnittstelle implizit abstrakt sind und keine Implementierungen haben können. Eine abstrakte Java-Klasse kann Instanzmethoden haben, die ein Standardverhalten implementieren.

2.Variablen, die in einer Java-Schnittstelle deklariert sind, sind standardmäßig final. Eine abstrakte Klasse kann nicht endgültige Variablen enthalten.

3. Mitglieder einer Java-Schnittstelle sind standardmäßig öffentlich. Eine abstrakte Java-Klasse kann die üblichen Varianten von Klassenmitgliedern wie privat, geschützt usw. haben.

4. Die Java-Schnittstelle sollte mit dem Schlüsselwort "implementiert" implementiert werden. Eine abstrakte Java-Klasse sollte mit dem Schlüsselwort "erweitert" erweitert werden.

5. Eine Schnittstelle kann nur eine andere Java-Schnittstelle erweitern, eine abstrakte Klasse kann eine andere Java-Klasse erweitern und mehrere Java-Schnittstellen implementieren.

6. Eine Java-Klasse kann mehrere Schnittstellen implementieren, jedoch nur eine abstrakte Klasse erweitern.

7. Die Schnittstelle ist absolut abstrakt und kann nicht instanziiert werden. Eine abstrakte Java-Klasse kann ebenfalls nicht instanziiert werden, kann jedoch aufgerufen werden, wenn ein main () vorhanden ist.

8. Im Vergleich zu abstrakten Java-Klassen sind Java-Schnittstellen langsam, da zusätzliche Indirektion erforderlich ist.

softmage99
quelle
3
Ich habe Ihre Antwort bearbeitet, um eine korrekte Zuordnung zu gewährleisten. Sie können nicht einfach einen Link am Ende Ihrer Antwort einfügen. Sie müssen auch die gesamte Sprache zitieren, die aus einer anderen Quelle kopiert wurde. Wenn diese Tabelle von irgendwoher stammt, sollten Sie außerdem klar angeben, woher diese stammt.
Brad Larson
Bitte erwähnen Sie dies auch für C ++. Es gibt zwar kein Schlüsselwort "interface" in C ++ als solches, aber es ist auch ein häufig gefragtes Qn regd C ++.
cbinder
@cbinder: In c ++ gibt es kein Schlüsselwort 'interface'.
Informationen zu
@MageshBabu Vielleicht macht das Definieren einer Funktion in einer Klasse, die eine reine virtuelle Funktion enthält, sie eher zu einer abstrakten Klasse als zur Schnittstelle
cbinder
2
Mit Java 8 sind die Unterschiede jetzt geringer. Überprüfen Sie aktualisierte Unterschiede hier: journaldev.com/1607/…
Pankaj
31

Der Hauptpunkt ist, dass:

  • Abstrakt ist objektorientiert . Es bietet die Basisdaten, die ein 'Objekt' haben sollte, und / oder Funktionen, die es ausführen kann. Es geht um die grundlegenden Eigenschaften des Objekts: Was es hat und was es kann. Daher teilen Objekte, die von derselben abstrakten Klasse erben, die grundlegenden Merkmale (Verallgemeinerung).
  • Die Schnittstelle ist funktionsorientiert . Es definiert Funktionen, die ein Objekt haben sollte. Unabhängig davon, um welches Objekt es sich handelt, ist es in Ordnung, solange diese Funktionen, die in der Benutzeroberfläche definiert sind, ausgeführt werden können. Es ignoriert alles andere. Ein Objekt / eine Klasse kann mehrere (Gruppen von) Funktionen enthalten. Daher kann eine Klasse mehrere Schnittstellen implementieren.
Moch Yusup
quelle
Vielen Dank, jetzt kommen wir mit einer guten Antwort auf hohem Niveau voran. Komisch, wie tief man in die Kommentare vordringen muss, um eine verständnisvollere Antwort zu finden.
Andrew
1
Die anderen Antworten sind zu technisch. Dies kommt zu dem, was ich für eine "richtige" Antwort halte. Der springende Punkt bei OOP ist die Semantik, und ob öffentliche Getter mit verschachtelten Klassen durch CPU-teure Suchvorgänge aufgerufen werden oder nicht, ist hier ziemlich irrelevant
Sentinel
26

Verwenden Sie abstrakte Klassen, wenn Sie polymorphes Verhalten in einer Vererbungshierarchie bereitstellen möchten.

Wenn Sie polymorphes Verhalten für Klassen wünschen, die völlig unabhängig sind, verwenden Sie eine Schnittstelle.

Bildhauer
quelle
24

Ich baue ein Gebäude mit 300 Stockwerken

Der Bauplan des Gebäudes Schnittstelle

  • Zum Beispiel Servlet (I)

Gebäude mit bis zu 200 Stockwerken - teilweise fertiggestellt --- abstrakt

  • Teilimplementierung, z. B. generisches und HTTP-Servlet

Hochbau fertiggestellt - Beton

  • Vollständige Implementierung, zum Beispiel eigenes Servlet

Schnittstelle

  • Wir wissen nichts über die Implementierung, nur Anforderungen. Wir können uns für eine Schnittstelle entscheiden.
  • Jede Methode ist standardmäßig öffentlich und abstrakt
  • Es ist eine 100% reine abstrakte Klasse
  • Wenn wir öffentlich erklären, können wir nicht privat und geschützt erklären
  • Wenn wir abstrakt deklarieren, können wir nicht final, statisch, synchronisiert, strictfp und native deklarieren
  • Jede Schnittstelle ist öffentlich, statisch und endgültig
  • Serialisierung und Transient sind nicht anwendbar, da wir keine Instanz für in der Schnittstelle erstellen können
  • Nicht flüchtig, weil es endgültig ist
  • Jede Variable ist statisch
  • Wenn wir eine Variable innerhalb einer Schnittstelle deklarieren, müssen wir während der Deklaration Variablen initialisieren
  • Instanz und statischer Block nicht erlaubt

Abstrakt

  • Teilweise Umsetzung
  • Es hat eine abstrakte Methode. Als Ergänzung wird Beton verwendet
  • Keine Einschränkung für Methodenmodifikatoren für abstrakte Klassen
  • Keine Einschränkung für abstrakte Klassenvariablenmodifikatoren
  • Wir können keine anderen Modifikatoren als abstrakt deklarieren
  • Keine Einschränkung zum Initialisieren von Variablen

Entnommen der DurgaJobs-Website

Jaichander
quelle
Eine abstrakte Klasse kann einen Konstruktor haben
vimal krishna
4
Ich stimme dieser Ansicht überhaupt nicht zu. Die Blaupause ist ein völlig anderes Konzept als "Schnittstelle". Blueprint entspricht eher einem statischen Modell oder einer Entwurfsspezifikation für eine bestimmte Implementierung. Es ist näher an 'Klasse', da die Blaupause über ihren Konstruktor mehrmals instanziiert werden kann, aber selbst dies ist nicht nah genug, da die 'Klasse' auch die Spezifikation für die Konstruktion (den ctor) und die zu erledigenden Mittel enthält damit. Schnittstelle als Konzept soll ein bestimmtes Verhalten darstellen, wie z. B. Aufheizen / Abkühlen, das auf verschiedene Bereiche angewendet werden kann, z. B. Gebäude, Öfen usw.
Sentinel,
18

Lassen Sie uns noch einmal an dieser Frage arbeiten:

Das erste, was Sie wissen lassen müssen, ist, dass 1/1 und 1 * 1 dasselbe ergeben, aber dies bedeutet nicht, dass Multiplikation und Division gleich sind. Offensichtlich haben sie eine gute Beziehung, aber wohlgemerkt, beide sind unterschiedlich.

Ich werde auf die Hauptunterschiede hinweisen, und der Rest wurde bereits erklärt:

Abstrakte Klassen sind nützlich zum Modellieren einer Klassenhierarchie. Auf den ersten Blick ist uns teilweise klar, was genau gebaut werden soll, aber wir wissen, was zu bauen ist. Und so sind Ihre abstrakten Klassen Ihre Basisklassen.

Schnittstellen sind nützlich, um anderen Hierarchien oder Klassen mitzuteilen, wozu ich in der Lage bin. Und wenn Sie sagen, dass ich zu etwas fähig bin, müssen Sie diese Fähigkeit haben. Schnittstellen markieren, dass eine Klasse dieselben Funktionen implementieren muss.

Dhananjay
quelle
2
Gute Antwort, aber die mathematische Metapher ist nutzlos und hat mich dazu gebracht, ungefähr die gleiche Zeit damit zu verschwenden, sie zu lesen, wie diesen Kommentar zu schreiben. Multiplizieren Sie dies nun mit allen anderen Personen, die diese Frage gelesen haben.
Andrew
"Mathe-Metapher ist nutzlos", warum denkst du so?
Dhananjay
12

Es ist eigentlich ziemlich einfach.

Sie können sich eine Schnittstelle als eine Klasse vorstellen, die nur abstrakte Methoden und nichts anderes haben darf.

Eine Schnittstelle kann also nur das Verhalten "deklarieren" und nicht definieren, das die Klasse haben soll.

Mit einer abstrakten Klasse können Sie sowohl das Verhalten der Klasse deklarieren (mit abstrakten Methoden) als auch definieren (mit vollständigen Methodenimplementierungen).

In einer regulären Klasse können Sie nur das Verhalten / die Aktionen definieren und nicht deklarieren, die die Klasse haben soll.

Eine letzte Sache,

In Java können Sie mehrere Schnittstellen implementieren, aber nur eine (abstrakte Klasse oder Klasse) erweitern ...

Dies bedeutet, dass die Vererbung von definiertem Verhalten nur eine pro Klasse zulässt. Wenn Sie also eine Klasse möchten, die Verhalten aus den Klassen A, B und C kapselt, müssen Sie Folgendes tun: Klasse A erweitert B, Klasse C erweitert A .. Es ist eine Art Umweg über Mehrfachvererbung ...

Schnittstellen hingegen können Sie einfach tun: Schnittstelle C implementiert A, B.

In der Tat unterstützt Java die Mehrfachvererbung nur in "deklariertem Verhalten", dh Schnittstellen, und nur die Einzelvererbung mit definiertem Verhalten.

Hoffentlich macht das Sinn.

g00dnatur3
quelle
11

Der Vergleich von Schnittstelle zu abstrakter Klasse ist falsch. Stattdessen sollten zwei weitere Vergleiche durchgeführt werden: 1) Schnittstelle vs. Klasse und 2) Zusammenfassung vs. Endklasse .

Schnittstelle gegen Klasse

Schnittstelle ist ein Vertrag zwischen zwei Objekten. ZB bin ich ein Postbote und du bist ein Paket zu liefern. Ich erwarte, dass Sie Ihre Lieferadresse kennen. Wenn mir jemand ein Paket gibt, muss er seine Lieferadresse kennen:

interface Package {
  String address();
}

Klasse ist eine Gruppe von Objekten, die dem Vertrag gehorchen. ZB bin ich eine Box aus der "Box" -Gruppe und halte mich an den vom Postboten geforderten Vertrag. Gleichzeitig gehorche ich anderen Verträgen:

class Box implements Package, Property {
  @Override
  String address() {
    return "5th Street, New York, NY";
  }
  @Override
  Human owner() {
    // this method is part of another contract
  }
}

Abstract vs Final

Die abstrakte Klasse ist eine Gruppe unvollständiger Objekte. Sie können nicht verwendet werden, da ihnen einige Teile fehlen. ZB bin ich eine abstrakte GPS-fähige Box - ich weiß, wie ich meine Position auf der Karte überprüfen kann:

abstract class GpsBox implements Package {
  @Override
  public abstract String address();
  protected Coordinates whereAmI() {
    // connect to GPS and return my current position
  }
}

Diese Klasse kann sehr nützlich sein, wenn sie von einer anderen Klasse geerbt / erweitert wird. Aber an sich - es ist nutzlos, da es keine Objekte haben kann. Abstrakte Klassen können Elemente von Abschlussklassen sein.

Die letzte Klasse ist eine Gruppe vollständiger Objekte, die verwendet, aber nicht geändert werden können. Sie wissen genau, wie man arbeitet und was zu tun ist. Ich bin beispielsweise eine Box, die immer an die Adresse geht, die während der Erstellung angegeben wurde:

final class DirectBox implements Package {
  private final String to;
  public DirectBox(String addr) {
    this.to = addr;
  }
  @Override
  public String address() {
    return this.to;
  }
}

In den meisten Sprachen wie Java oder C ++ ist es möglich, nur eine Klasse zu haben , weder abstrakt noch endgültig. Eine solche Klasse kann vererbt und instanziiert werden. Ich denke jedoch nicht, dass dies streng im Einklang mit dem objektorientierten Paradigma steht.

Auch hier ist der Vergleich von Schnittstellen mit abstrakten Klassen nicht korrekt.

yegor256
quelle
9

Kurz gesagt, die Unterschiede sind folgende:

Syntaktische Unterschiede zwischen Schnittstelle und abstrakter Klasse :

  1. Methoden und Mitglieder einer abstrakten Klasse können jede Sichtbarkeit haben. Alle Methoden einer Schnittstelle müssen öffentlich sein . // Gilt nicht mehr für Java 9
  2. Eine konkrete untergeordnete Klasse einer abstrakten Klasse muss alle abstrakten Methoden definieren. Eine abstrakte untergeordnete Klasse kann abstrakte Methoden haben. Eine Schnittstelle , die eine andere Schnittstelle erweitert, muss keine Standardimplementierung für Methoden bereitstellen, die von der übergeordneten Schnittstelle geerbt wurden.
  3. Eine untergeordnete Klasse kann nur eine einzelne Klasse erweitern. Eine Schnittstelle kann mehrere Schnittstellen erweitern. Eine Klasse kann mehrere Schnittstellen implementieren.
  4. Eine untergeordnete Klasse kann abstrakte Methoden mit derselben oder einer weniger restriktiven Sichtbarkeit definieren, während eine Klasse, die eine Schnittstelle implementiert , alle Schnittstellenmethoden als öffentlich definieren muss.
  5. Abstrakte Klassen können Konstruktoren, aber keine Schnittstellen haben .
  6. Schnittstellen von Java 9 verfügen über private statische Methoden.

In Interfaces jetzt:

public static- unterstützt
public abstract- unterstützt
public default- unterstützt
private static- unterstützt
private abstract- Kompilierungsfehler
private default- Kompilierungsfehler
private- unterstützt

Pritam Banerjee
quelle
8

Der einzige Unterschied besteht darin, dass man an Mehrfachvererbung teilnehmen kann und andere nicht.

Die Definition einer Schnittstelle hat sich im Laufe der Zeit geändert. Denken Sie, dass eine Schnittstelle nur Methodendeklarationen enthält und nur Verträge sind? Was ist mit statischen Endvariablen und was ist mit Standarddefinitionen nach Java 8?

Schnittstellen wurden aufgrund des Diamantproblems mit Mehrfachvererbung in Java eingeführt, und genau das beabsichtigen sie tatsächlich zu tun.

Schnittstellen sind die Konstrukte, die erstellt wurden, um das Problem der Mehrfachvererbung zu lösen. Sie können abstrakte Methoden, Standarddefinitionen und statische Endvariablen enthalten.

Siehe Warum erlaubt Java statische endgültige Variablen in Schnittstellen, wenn sie nur als Verträge gedacht sind? .

Vivek Vermani
quelle
1
Das ist zwar ein wichtiger Unterschied, aber nicht der einzige.
Govind Parmar
7

Schnittstelle: Abbiegen (links abbiegen, rechts abbiegen.)

Abstrakte Klasse: Rad.

Klasse: Lenkrad, stammt vom Rad, legt die Schnittstellendrehung frei

Eine dient zur Kategorisierung von Verhalten, das für eine Vielzahl von Dingen angeboten werden kann, die andere zur Modellierung einer Ontologie von Dingen.

Wächter
quelle
6

Wenn Sie einige allgemeine Methoden haben, die von mehreren Klassen verwendet werden können, wählen Sie abstrakte Klassen. Wenn Sie möchten, dass die Klassen einem bestimmten Entwurf folgen, wählen Sie Schnittstellen.

Die folgenden Beispiele zeigen dies.

Abstrakte Klasse in Java:

abstract class animals
{
    // They all love to eat. So let's implement them for everybody
    void eat()
    {
        System.out.println("Eating...");
    }
    // The make different sounds. They will provide their own implementation.
    abstract void sound();
}

class dog extends animals
{
    void sound()
    {
        System.out.println("Woof Woof");
    }
}

class cat extends animals
{
    void sound()
    {
        System.out.println("Meoww");
    }
}

Es folgt eine Implementierung der Schnittstelle in Java:

interface Shape
{
    void display();
    double area();
}

class Rectangle implements Shape 
{
    int length, width;
    Rectangle(int length, int width)
    {
        this.length = length;
        this.width = width;
    }
    @Override
    public void display() 
    {
        System.out.println("****\n* *\n* *\n****"); 
    }
    @Override
    public double area() 
    {
        return (double)(length*width);
    }
} 

class Circle implements Shape 
{
    double pi = 3.14;
    int radius;
    Circle(int radius)
    {
        this.radius = radius;
    }
    @Override
    public void display() 
    {
        System.out.println("O"); // :P
    }
    @Override
    public double area() 
    { 
        return (double)((pi*radius*radius)/2);
    }
}

Einige wichtige wichtige Punkte auf den Punkt gebracht:

  1. Die in der Java-Schnittstelle deklarierten Variablen sind standardmäßig final. Abstrakte Klassen können nicht endgültige Variablen haben.

  2. Die in der Java-Schnittstelle deklarierten Variablen sind standardmäßig statisch. Abstrakte Klassen können nicht statische Variablen haben.

  3. Mitglieder einer Java-Schnittstelle sind standardmäßig öffentlich. Eine abstrakte Java-Klasse kann die üblichen Varianten von Klassenmitgliedern wie privat, geschützt usw. haben.

Pransh Tiwari
quelle
4

Viele Nachwuchsentwickler machen den Fehler, Schnittstellen, abstrakte und konkrete Klassen als geringfügige Abweichungen derselben zu betrachten, und wählen eine davon nur aus technischen Gründen: Brauche ich Mehrfachvererbung? Benötige ich einen Platz, um gängige Methoden anzuwenden? Muss ich mich mit etwas anderem als nur einer konkreten Klasse beschäftigen? Das ist falsch und in diesen Fragen verbirgt sich das Hauptproblem: "Ich" . Wenn Sie selbst Code schreiben, denken Sie selten an andere gegenwärtige oder zukünftige Entwickler, die an oder mit Ihrem Code arbeiten.

Schnittstellen und abstrakte Klassen haben, obwohl sie aus technischer Sicht offensichtlich ähnlich sind, völlig unterschiedliche Bedeutungen und Zwecke.

Zusammenfassung

  1. Eine Schnittstelle definiert einen Vertrag , den eine Implementierung für Sie erfüllen wird .

  2. Eine abstrakte Klasse bietet ein Standardverhalten, das Ihre Implementierung wiederverwenden kann.

Alternative Zusammenfassung

  1. Eine Schnittstelle dient zum Definieren öffentlicher APIs
  2. Eine abstrakte Klasse ist für den internen Gebrauch und zum Definieren von SPIs vorgesehen

Über die Wichtigkeit, Implementierungsdetails zu verbergen

Eine konkrete Klasse erledigt die eigentliche Arbeit auf ganz bestimmte Weise. Beispielsweise ArrayListverwendet a einen zusammenhängenden Speicherbereich, um eine Liste von Objekten auf kompakte Weise zu speichern, die schnellen Direktzugriff, Iteration und direkte Änderungen bietet, aber beim Einfügen, Löschen und gelegentlich sogar beim Hinzufügen schrecklich ist. In der Zwischenzeit LinkedListverwendet a doppelt verknüpfte Knoten, um eine Liste von Objekten zu speichern, die stattdessen eine schnelle Iteration, direkte Änderungen und das Einfügen / Löschen / Hinzufügen bietet, aber bei wahlfreiem Zugriff schrecklich ist. Diese beiden Arten von Listen sind für verschiedene Anwendungsfälle optimiert, und es ist sehr wichtig, wie Sie sie verwenden werden. Wenn Sie versuchen, die Leistung aus einer Liste herauszuholen, mit der Sie stark interagieren, und wenn Sie die Art der Liste auswählen, sollten Sie sorgfältig auswählen, welche Sie instanziieren.

Auf der anderen Seite ist es hochrangigen Benutzern einer Liste egal, wie sie tatsächlich implementiert wird, und sie sollten von diesen Details isoliert sein. Stellen wir uns vor, Java hat die ListSchnittstelle nicht verfügbar gemacht , sondern nur eine konkrete ListKlasse, die LinkedListgenau das ist, was gerade ist. Alle Java-Entwickler hätten ihren Code an die Implementierungsdetails angepasst: Vermeiden Sie Direktzugriff, fügen Sie einen Cache hinzu, um den Zugriff zu beschleunigen, oder implementieren ArrayListSie ihn einfach selbst neu, obwohl er nicht mit allen anderen Codes kompatibel wäre, die tatsächlich nur funktionieren List. Das wäre schrecklich ... Aber stellen Sie sich jetzt vor, dass die Java-Master tatsächlich erkennen, dass eine verknüpfte Liste für die meisten tatsächlichen Anwendungsfälle schrecklich ist, und beschlossen, nur für ihre auf eine Array-Liste umzuschaltenListKlasse verfügbar. Dies würde die Leistung jedes Java-Programms auf der Welt beeinträchtigen, und die Leute würden sich nicht darüber freuen. Der Hauptschuldige ist, dass Implementierungsdetails verfügbar waren, und die Entwickler gingen davon aus, dass diese Details ein dauerhafter Vertrag sind, auf den sie sich verlassen können. Aus diesem Grund ist es wichtig, Implementierungsdetails auszublenden und nur einen abstrakten Vertrag zu definieren. Dies ist der Zweck einer Schnittstelle: Definieren Sie, welche Art von Eingabe eine Methode akzeptiert und welche Art von Ausgabe erwartet wird, ohne alle Eingeweide aufzudecken, die Programmierer dazu verleiten würden, ihren Code so anzupassen, dass er den internen Details entspricht, die sich bei zukünftigen Updates ändern könnten .

Eine abstrakte Klasse befindet sich in der Mitte zwischen Schnittstellen und konkreten Klassen. Es soll Implementierungen helfen, gemeinsamen oder langweiligen Code zu teilen. Zum Beispiel AbstractCollectionbietet grundlegende Implementierungen für isEmptybasierend auf der Größe 0 ist, containsals Iterierte und vergleichen, addAllwie wiederholtadd , und so weiter. Auf diese Weise können sich Implementierungen auf die entscheidenden Teile konzentrieren, die zwischen ihnen unterscheiden: das tatsächliche Speichern und Abrufen von Daten.

APIs versus SPIs

Schnittstellen sind Gateways mit geringer Kohäsion zwischen verschiedenen Teilen des Codes. Sie ermöglichen es Bibliotheken, zu existieren und sich weiterzuentwickeln, ohne jeden Bibliotheksbenutzer zu beschädigen, wenn sich intern etwas ändert. Es heißt Application Programming Interface - nicht Application Programming Klassen. In kleinerem Maßstab ermöglichen sie auch mehreren Entwicklern die erfolgreiche Zusammenarbeit bei großen Projekten, indem sie verschiedene Module durch gut dokumentierte Schnittstellen trennen.

Abstrakte Klassen sind hochkohäsive Helfer , die bei der Implementierung einer Schnittstelle verwendet werden können, sofern ein gewisses Maß an Implementierungsdetails vorausgesetzt wird. Alternativ werden abstrakte Klassen zum Definieren von SPIs (Service Provider Interfaces) verwendet.

Der Unterschied zwischen einer API und einem SPI ist subtil, aber wichtig: Bei einer API liegt der Fokus darauf, wer sie verwendet , und bei einem SPI liegt der Fokus darauf, wer sie implementiert .

Das Hinzufügen von Methoden zu einer API ist einfach. Alle vorhandenen Benutzer der API werden weiterhin kompiliert. Das Hinzufügen von Methoden zu einem SPI ist schwierig, da jeder Dienstanbieter (konkrete Implementierung) die neuen Methoden implementieren muss. Wenn zum Definieren eines SPI Schnittstellen verwendet werden, muss ein Anbieter bei jeder Änderung des SPI-Vertrags eine neue Version veröffentlichen. Wenn stattdessen abstrakte Klassen verwendet werden, können neue Methoden entweder als vorhandene abstrakte Methoden oder als leere throw not implemented exceptionStubs definiert werden, wodurch zumindest eine ältere Version einer Service-Implementierung weiterhin kompiliert und ausgeführt werden kann.

Ein Hinweis zu Java 8 und Standardmethoden

Obwohl Java 8 Standardmethoden für Schnittstellen eingeführt hat, die die Grenze zwischen Schnittstellen und abstrakten Klassen noch unschärfer machen, war dies nicht so, dass Implementierungen Code wiederverwenden können, sondern um das Ändern von Schnittstellen zu erleichtern, die sowohl als API als auch als SPI dienen (oder werden fälschlicherweise zum Definieren von SPIs anstelle von abstrakten Klassen verwendet).

Welches verwenden?

  1. Ist die Sache anzunehmen, öffentlich verwendet durch andere Teile des Codes, oder von anderen externen Code? Fügen Sie eine Schnittstelle hinzu, um die Implementierungsdetails vor dem öffentlichen abstrakten Vertrag zu verbergen, der das allgemeine Verhalten der Sache darstellt.
  2. Ist das Ding etwas, das mehrere Implementierungen mit viel Code gemeinsam haben soll? Erstellen Sie sowohl eine Schnittstelle als auch eine abstrakte, unvollständige Implementierung.
  3. Wird es jemals nur eine Implementierung geben, und niemand anderes wird sie verwenden? Machen Sie es einfach zu einer konkreten Klasse.
    1. "ever" ist lange Zeit, Sie könnten auf Nummer sicher gehen und trotzdem eine Schnittstelle hinzufügen.

Eine Konsequenz: Der umgekehrte Weg wird oft falsch gemacht: Wenn Sie etwas verwenden , versuchen Sie immer, die allgemeinste Klasse / Schnittstelle zu verwenden, die Sie tatsächlich benötigen. Mit anderen Worten, deklarieren Sie Ihre Variablen nicht als ArrayList theList = new ArrayList(), es sei denn, Sie haben tatsächlich eine sehr starke Abhängigkeit davon, dass es sich um eine Array- Liste handelt, und kein anderer Listentyp würde sie für Sie ausschneiden. Verwenden Sie List theList = new ArrayListstattdessen oder auch Collection theCollection = new ArrayListwenn die Tatsache, dass es sich um eine Liste handelt und keine andere Art von Sammlung, keine Rolle spielt.

Sergiu Dumitriu
quelle
4

Nicht wirklich die Antwort auf die ursprüngliche Frage, aber sobald Sie die Antwort auf den Unterschied zwischen ihnen haben, werden Sie in das Dilemma der Verwendungsmöglichkeiten für jedes eingehen: Wann werden Schnittstellen oder abstrakte Klassen verwendet? Wann beides verwenden?

Ich habe nur begrenzte Kenntnisse über OOP, aber Schnittstellen als Äquivalent eines Adjektivs in der Grammatik zu sehen, hat bis jetzt für mich funktioniert (korrigieren Sie mich, wenn diese Methode falsch ist!). Beispielsweise sind Schnittstellennamen wie Attribute oder Funktionen, die Sie einer Klasse geben können, und eine Klasse kann viele davon haben: ISerializable, ICountable, IList, ICacheable, IHappy, ...

Azkotoki
quelle
3

Die Vererbung wird für zwei Zwecke verwendet:

  • Damit ein Objekt übergeordnete Datenelemente und Methodenimplementierungen als seine eigenen betrachten kann.

  • Damit kann ein Verweis auf ein Objekt eines Typs von Code verwendet werden, der einen Verweis auf ein Objekt vom Supertyp erwartet.

In Sprachen / Frameworks, die eine verallgemeinerte Mehrfachvererbung unterstützen, besteht häufig nur eine geringe Notwendigkeit, einen Typ entweder als "Schnittstelle" oder als "abstrakte Klasse" zu klassifizieren. In gängigen Sprachen und Frameworks kann ein Typ jedoch die Datenelemente oder Methodenimplementierungen eines anderen Typs als seine eigenen betrachten, obwohl ein Typ durch eine beliebige Anzahl anderer Typen ersetzt werden kann.

Abstrakte Klassen können Datenelemente und Methodenimplementierungen haben, können jedoch nur von Klassen geerbt werden, die keine anderen Klassen erben. Schnittstellen beschränken die Typen, die sie implementieren, fast nicht, können jedoch keine Datenelemente oder Methodenimplementierungen enthalten.

Es gibt Zeiten, in denen es nützlich ist, wenn Typen durch viele verschiedene Dinge ersetzt werden können. Es gibt andere Zeiten, in denen es für Objekte nützlich ist, übergeordnete Datenelemente und Methodenimplementierungen als ihre eigenen zu betrachten. Durch die Unterscheidung zwischen Schnittstellen und abstrakten Klassen kann jede dieser Fähigkeiten in Fällen eingesetzt werden, in denen sie am relevantesten ist.

Superkatze
quelle
3

Wichtige Punkte:

  • Die abstrakte Klasse kann beide Eigenschaften, Datenfelder und Methoden (vollständig / unvollständig) enthalten.
  • Wenn Methode oder Eigenschaften in einem abstrakten Schlüsselwort definiert sind, das in der abgeleiteten Klasse überschrieben werden muss (ihre Arbeit als eng gekoppelte Funktionalität)
  • Wenn Sie ein abstraktes Schlüsselwort für eine Methode oder Eigenschaften in einer abstrakten Klasse definieren, können Sie keinen Methodenkörper definieren und keinen Wert für Eigenschaften abrufen / festlegen, der in der abgeleiteten Klasse überschrieben werden muss.
  • Die abstrakte Klasse unterstützt keine Mehrfachvererbung.
  • Die abstrakte Klasse enthält Konstruktoren.
  • Eine abstrakte Klasse kann Zugriffsmodifikatoren für die Subs, Funktionen und Eigenschaften enthalten.
  • Nur das vollständige Mitglied der abstrakten Klasse kann statisch sein.
  • Eine Schnittstelle kann nur von einer anderen Schnittstelle erben und nicht von einer abstrakten Klasse, während eine abstrakte Klasse von einer anderen abstrakten Klasse oder einer anderen Schnittstelle erben kann.

Vorteil:

  • Es ist eine Art Vertrag, der alle Unterklassen dazu zwingt, dieselben Hierarchien oder Standards beizubehalten.
  • Wenn verschiedene Implementierungen von derselben Art sind und gemeinsames Verhalten oder Status verwenden, ist es besser, eine abstrakte Klasse zu verwenden.
  • Wenn wir einer abstrakten Klasse eine neue Methode hinzufügen, haben wir die Möglichkeit, eine Standardimplementierung bereitzustellen, und daher funktioniert möglicherweise der gesamte vorhandene Code ordnungsgemäß.
  • Es ermöglicht eine schnelle Ausführung als die Schnittstelle. (Schnittstelle Benötigt mehr Zeit, um die eigentliche Methode in den entsprechenden Klassen zu finden.)
  • Es kann für eine enge und lose Kupplung verwendet werden.

Details finden Sie hier ... http://pradeepatkari.wordpress.com/2014/11/20/interface-and-abstract-class-in-c-oops/

Pradeep atkari
quelle
3

Der kürzeste Weg, um es zusammenzufassen, interfaceist:

  1. Vollständig abstrakt, abgesehen von defaultund staticMethoden; Während es Definitionen (Methodensignaturen + Implementierungen) für defaultund staticMethoden enthält, enthält es nur Deklarationen (Methodensignaturen) für andere Methoden.
  2. Vorbehaltlich lockerer Regeln als Klassen (eine Klasse kann mehrere interfaces implementieren und eine interfacevon mehreren interfaces erben ). Alle Variablen sind implizit konstant, unabhängig davon, ob sie als angegeben sind public static finaloder nicht. Alle Mitglieder sind implizit public, ob als solche angegeben oder nicht.
  3. Wird im Allgemeinen als Garantie dafür verwendet, dass die implementierende Klasse über die angegebenen Funktionen verfügt und / oder mit jeder anderen Klasse kompatibel ist, die dieselbe Schnittstelle implementiert.

Inzwischen ist eine abstractKlasse:

  1. Von vollständig abstrakt bis vollständig implementiert, mit der Tendenz, eine oder mehrere abstractMethoden zu haben. Kann sowohl Deklarationen als auch Definitionen enthalten, wobei die Deklarationen als gekennzeichnet sind abstract.
  2. Eine vollwertige Klasse, die den Regeln unterliegt, die andere Klassen regeln (kann nur von einer Klasse erben), unter der Bedingung, dass sie nicht instanziiert werden kann (da nicht garantiert werden kann, dass sie vollständig implementiert ist). Kann nicht konstante Mitgliedsvariablen haben. Kann Mitglied Zugangskontrolle, Begrenzungselemente wie implementieren protected, privateoder privates Paket (nicht spezifiziert).
  3. Wird im Allgemeinen verwendet, um entweder so viel von der Implementierung bereitzustellen, wie von mehreren Unterklassen gemeinsam genutzt werden kann, oder um so viel von der Implementierung bereitzustellen, wie der Programmierer bereitstellen kann.

Oder wenn wir alles auf einen einzigen Satz reduzieren wollen: An interfaceist das, was die implementierende Klasse hat , aber eine abstractKlasse ist das, was die Unterklasse ist .

Justin Time - Monica wieder einsetzen
quelle
3

Ich möchte noch einen Unterschied hinzufügen, der Sinn macht. Sie haben beispielsweise ein Framework mit Tausenden von Codezeilen. Wenn Sie nun mit einer Methode boostUI () eine neue Funktion im gesamten Code hinzufügen möchten, ist es besser, diese Methode in der abstrakten Klasse und nicht in der Schnittstelle hinzuzufügen. Wenn Sie diese Methode in eine Schnittstelle einfügen, sollten Sie sie in der gesamten implementierten Klasse implementieren. Dies ist jedoch nicht der Fall, wenn Sie die Methode in der abstrakten Klasse hinzufügen.

Zahnlos
quelle
3

Um eine einfache, aber klare Antwort zu geben, ist es hilfreich, den Kontext festzulegen: Sie verwenden beide, wenn Sie keine vollständigen Implementierungen bereitstellen möchten.

Der Hauptunterschied besteht dann darin, dass eine Schnittstelle überhaupt keine Implementierung hat (nur Methoden ohne Body), während abstrakte Klassen auch Mitglieder und Methoden mit einem Body haben können, dh teilweise implementiert werden können.

user3775501
quelle
Da Sie es gerade beantwortet haben, berücksichtigt Ihre Antwort nicht das defaultSchlüsselwort in Java 8, mit dem Sie konkrete Methoden auch in Schnittstellen definieren können.
Philantrovert
Wie gesagt, dies sollte eine "einfache, aber klare Antwort" für jemanden sein, der gerade lernt, was der Unterschied ist. Für jemanden wie diesen ist es nicht von Vorteil, über diese Art von Ausnahme Bescheid zu wissen, es wäre nur sehr verwirrend.
user3775501
3

Unterschiede zwischen abstrakter Klasse und Schnittstelle im Namen der tatsächlichen Implementierung.

Schnittstelle : Es ist ein Schlüsselwort und wird zum Definieren der Vorlage oder des Entwurfs eines Objekts verwendet. Es erzwingt, dass alle Unterklassen demselben Prototyp folgen, da bei der Implementierung alle Unterklassen frei sind, die Funktionalität gemäß zu implementieren es ist Voraussetzung.

Einige andere Anwendungsfälle, in denen wir die Schnittstelle verwenden sollten.

Kommunikation zwischen zwei externen Objekten (Integration durch Dritte in unsere Anwendung) über Interface here Interface funktioniert als Vertrag.

Abstrakte Klasse: Abstrakt, es ist ein Schlüsselwort, und wenn wir dieses Schlüsselwort vor einer Klasse verwenden, wird es zu einer abstrakten Klasse. Es wird hauptsächlich verwendet, wenn wir die Vorlage sowie einige Standardfunktionen eines Objekts definieren müssen, denen alle folgen Unterklassen und auf diese Weise wird der redundante Code entfernt und ein weiterer Anwendungsfall, in dem wir abstrakte Klassen verwenden können , wie wir möchten, dass keine anderen Klassen ein Objekt der Klasse direkt instanziieren können, nur abgeleitete Klassen können die Funktionalität verwenden.

Beispiel für eine abstrakte Klasse:

 public abstract class DesireCar
  {

 //It is an abstract method that defines the prototype.
     public abstract void Color();

  // It is a default implementation of a Wheel method as all the desire cars have the same no. of wheels.   
 // and hence no need to define this in all the sub classes in this way it saves the code duplicasy     

  public void Wheel() {          

               Console.WriteLine("Car has four wheel");
                }
           }


    **Here is the sub classes:**

     public class DesireCar1 : DesireCar
        {
            public override void Color()
            {
                Console.WriteLine("This is a red color Desire car");
            }
        }

        public class DesireCar2 : DesireCar
        {
            public override void Color()
            {
                Console.WriteLine("This is a red white Desire car");
            }
        }

Beispiel einer Schnittstelle:

  public interface IShape
        {
          // Defines the prototype(template) 
            void Draw();
        }


  // All the sub classes follow the same template but implementation can be different.

    public class Circle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("This is a Circle");
        }
    }

    public class Rectangle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("This is a Rectangle");
        }
    }
Sheo Dayal Singh
quelle
3

Sie können einen deutlichen Unterschied zwischen Schnittstelle und abstrakter Klasse feststellen .

Schnittstelle

  • Die Schnittstelle enthält nur abstrakte Methoden.
  • Benutzer zwingen, alle Methoden zu implementieren, wenn die Schnittstelle implementiert wird.
  • Enthält nur endgültige und statische Variablen.
  • Deklarieren Sie mit dem Schlüsselwort interface.
  • Alle Methoden einer Schnittstelle müssen als öffentlich definiert sein.
  • Eine Schnittstelle kann erweitert werden oder eine Klasse kann mehrere andere Schnittstellen implementieren.

Abstrakte Klasse

  • Die abstrakte Klasse enthält abstrakte und nicht abstrakte Methoden.

  • Erzwingt nicht, dass Benutzer alle Methoden implementieren, wenn die abstrakte Klasse geerbt wird.

  • Enthält alle Arten von Variablen, einschließlich primitiver und nicht primitiver Variablen

  • Mit dem abstrakten Schlüsselwort deklarieren.

  • Methoden und Mitglieder einer abstrakten Klasse können mit jeder Sichtbarkeit definiert werden.

  • Eine untergeordnete Klasse kann nur eine einzelne Klasse (abstrakt oder konkret) erweitern.

Rahul Chauhan
quelle
2

Eine abstrakte Klasse ist eine Klasse, deren Objekt nicht erstellt werden kann, oder eine Klasse, die nicht instanziiert werden kann. Eine abstrakte Methode macht eine Klasse abstrakt. Eine abstrakte Klasse muss geerbt werden, um die in der abstrakten Klasse deklarierten Methoden zu überschreiben. Keine Einschränkung für Zugriffsspezifizierer. Eine abstrakte Klasse kann Konstruktor- und andere konkrete Methoden (nicht abstrakt) enthalten, die Schnittstelle jedoch nicht.

Eine Schnittstelle ist eine Blaupause / Vorlage von Methoden (z. B. ein Haus auf einem Papier wird angegeben (Schnittstellenhaus), und verschiedene Architekten verwenden ihre Ideen, um sie zu erstellen (die Klassen von Architekten, die die Hausschnittstelle implementieren). Es handelt sich um eine Sammlung von abstrakte Methoden, Standardmethoden, statische Methoden, endgültige Variablen und verschachtelte Klassen. Alle Mitglieder sind entweder endgültige oder öffentliche, geschützte und private Zugriffsspezifizierer sind nicht zulässig. Es ist keine Objekterstellung zulässig. Eine Klasse muss erstellt werden, um die zu verwenden Eine Schnittstelle ist ein gutes Beispiel für lose Kopplung (dynamischer Polymorphismus / dynamische Bindung). Eine Schnittstelle implementiert Polymorphismus und Abstraktion. Sie gibt an, was zu tun ist, aber wie zu tun ist Implementierungsklasse. Zum Beispiel dort. 'Eine Autofirma, und sie möchte, dass einige Funktionen für alle von ihr hergestellten Autos gleich sind, damit die Firma ein Schnittstellenfahrzeug herstellt, das diese Funktionen aufweist und verschiedene Fahrzeugklassen (wie Maruti Suzkhi, Maruti 800) außer Kraft setzen diese Merkmale (Funktionen).

Warum Schnittstelle, wenn wir bereits eine abstrakte Klasse haben? Java unterstützt nur mehrstufige und hierarchische Vererbung, aber mit Hilfe der Schnittstelle können wir Mehrfachvererbung implementieren.

Tutu Kumari
quelle
2

In praktischer Hinsicht (JAVA) besteht der Hauptunterschied zwischen abstrakter Klasse und Schnittstelle darin, dass die abstrakte Klasse den Status halten kann. Neben dem Haltezustand können wir auch mit Interface Ruhevorgänge ausführen.

Tokala Sai Teja
quelle
1

In einer Schnittstelle dürfen alle Methoden nur Definitionen sein, es sollte keine einzelne implementiert werden.

Aber in einer abstrakten Klasse muss es eine abstrakte Methode mit nur Definition geben, aber andere Methoden können auch in der abstrakten Klasse mit Implementierung sein ...

Shamim Ahmed
quelle
1

Wir haben verschiedene strukturelle / syntaktische Unterschiede zwischen Schnittstelle und abstrakter Klasse. Einige weitere Unterschiede sind

[1] Szenariobasierter Unterschied :

Abstrakte Klassen werden in Szenarien verwendet, in denen wir den Benutzer darauf beschränken möchten, ein Objekt der übergeordneten Klasse zu erstellen, UND wir glauben, dass in Zukunft weitere abstrakte Methoden hinzugefügt werden.

Die Schnittstelle muss verwendet werden, wenn wir sicher sind, dass keine abstraktere Methode mehr bereitgestellt werden kann. Dann wird nur eine Schnittstelle veröffentlicht.

[2] Konzeptioneller Unterschied :

"Müssen wir in Zukunft abstraktere Methoden bereitstellen?" Wenn YES es zu einer abstrakten Klasse macht und NEIN es zu einer Schnittstelle macht.

(Am besten geeignet und gültig bis Java 1.7)

Shashank Bodkhe
quelle
1

Normalerweise wird die abstrakte Klasse für den Kern von etwas verwendet, aber die Schnittstelle zum Anhängen von Peripheriegeräten.

Wenn Sie einen Basistyp für ein Fahrzeug erstellen möchten, sollten Sie eine abstrakte Klasse verwenden. Wenn Sie jedoch Funktionen oder Eigenschaften hinzufügen möchten, die nicht Teil des Basiskonzepts eines Fahrzeugs sind, sollten Sie die Schnittstelle verwenden, z. B. die Funktion "ToJSON ()" hinzufügen .

Die Schnittstelle hat eher einen breiten Abstraktionsbereich als eine abstrakte Klasse. Sie können dies an übergebenen Argumenten sehen. Sehen Sie sich dieses Beispiel an:

Geben Sie hier die Bildbeschreibung ein

Wenn Sie ein Fahrzeug als Argument verwenden, können Sie nur einen der abgeleiteten Typen verwenden (Bus oder Auto - gleiche Kategorie - nur Fahrzeugkategorie). Wenn Sie jedoch die IMoveable-Schnittstelle als Argument verwenden, haben Sie mehr Auswahlmöglichkeiten.

MRMF
quelle