Was genau ist der Unterschied zwischen einer Schnittstelle und einer abstrakten Klasse?
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 Weg ".
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 (Pseudo-Code):
// 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 um eine Reihe von Namen handelt und daher kein teures Nachschlagen erforderlich ist. Es ist großartig, wenn es darauf ankommt, beispielsweise bei eingebetteten Geräten.
Abstrakte Klassen sind im Gegensatz zu Schnittstellen Klassen. Sie sind teurer in der Verwendung, da nachgeschlagen werden muss, wenn Sie von ihnen erben.
Abstrakte Klassen sehen sehr wie Schnittstellen aus, haben aber noch etwas mehr: Sie können ein Verhalten für sie definieren. Es geht eher darum, dass eine Person 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");
}
}
Während abstrakte Klassen und Interfaces unterschiedliche Konzepte sein sollen, machen diese 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 abstrakte Klassen ohne deklarierte Methode sind.
In Python sind abstrakte Klassen eher ein Programmier-Trick, den Sie mit dem ABC-Modul erhalten können, und verwendet eigentlich Metaklassen und daher Klassen. Interfaces beziehen sich eher auf das Eingeben von Enten in dieser Sprache und es ist eine Mischung aus Konventionen und speziellen Methoden, die Deskriptoren aufrufen (die __method__-Methoden).
Wie üblich beim Programmieren gibt es Theorie, Praxis und Praxis in einer anderen Sprache :-)
Die wichtigsten technischen Unterschiede zwischen einer abstrakten Klasse und einer Schnittstelle sind:
Abstrakte Klassen können Konstanten, Member, Methodenstubs (Methoden ohne Rumpf) und definierte Methoden haben, während Schnittstellen nur Konstanten und Methodenstubs haben können.
Methoden und Member einer abstrakten Klasse können mit beliebige Sichtbarkeit definiert werden, während alle Methoden eines Interfaces als public
definiert sein müssen (sie sind standardmäßig als öffentlich definiert).
Beim Erben einer abstrakten Klasse kann eine konkrete Kindklasse muss die abstrakten Methoden definieren, während eine abstrakte Klasse eine andere abstrakte Klasse erweitern kann und abstrakte Methoden der übergeordneten Klasse nicht sein müssen definiert.
In ähnlicher Weise ist eine Schnittstelle, die eine andere Schnittstelle erweitert, nicht für die Implementierung von Methoden verantwortlich von der übergeordneten Schnittstelle. Dies liegt daran, dass Schnittstellen keine Implementierung definieren können.
Eine untergeordnete Klasse kann nur eine einzige Klasse erweitern (abstrakt oder konkret), wohingegen eine Schnittstelle erweitert werden kann oder eine Klasse mehrere andere Schnittstellen implementieren.
Eine untergeordnete Klasse kann abstrakte Methoden mit der gleichen oder weniger einschränkenden Sichtbarkeit definieren, während eine Klasse, die eine Schnittstelle implementiert, die Methoden mit genau derselben Sichtbarkeit (öffentlich) definieren muss.
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 gleichzeitig Verhalten und Funktionalität bereitstellen. Ein anderer Entwickler, der die abstrakte Klasse erbt, kann diese Funktionalität problemlos verwenden, da er nur die Lücken ausfüllen muss.
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.htmlhttp://www.dotnetbull.com/2011/ 11/Was ist-Schnittstelle-in-c-net.html
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 nur teilweise implementiert durch die Programmierer. Es kann ein oder mehrere .__ enthalten. abstrakte Methoden. Eine abstrakte Methode ist einfach eine Funktionsdefinition, die dient dazu, dem Programmierer mitzuteilen, dass die Methode muss in einem Kind implementiert werden Klasse.
Eine Schnittstelle ähnelt einer Zusammenfassung Klasse; In der Tat besetzen Schnittstellen die derselbe Namensraum wie Klassen und Abstract Klassen. Aus diesem Grund können Sie nicht Definieren Sie eine Schnittstelle mit demselben Namen als eine Klasse. Eine Schnittstelle ist vollständig abstrakte Klasse; keine seiner Methoden implementiert sind und statt einer Klasse Es wird gesagt, dass. implementiere diese Schnittstelle.
Trotzdem finde ich diese Erklärung von Schnittstellen etwas verwirrend. Eine gebräuchlichere Definition ist: Eine Schnittstelle definiert einen Vertrag, den implementierende Klassen erfüllen müssen. Eine Schnittstellendefinition besteht aus Signaturen öffentlicher Mitglieder ohne Implementierungscode.
Ich möchte nicht die Unterschiede hervorheben, die bereits in vielen Antworten erwähnt wurden (bezüglich öffentlicher statischer Modifikatoren 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:
interface: Um einen Vertrag durch mehrere nicht zusammenhängende Objekte zu implementieren
abstract class: Um dasselbe oder unterschiedliches Verhalten unter mehreren verwandten Objekten zu implementieren
Aus dem Oracle Dokumentation
Erwägen Sie die Verwendung abstrakter Klassen, wenn:
Erwägen Sie die Verwendung von Interfaces, wenn:
Serializable
-Schnittstelle implementieren.abstract class stellt "eine" Beziehung zu konkreten Klassen her. Schnittstelle bietet "hat eine" Fähigkeit für Klassen.
Wenn Sie nach Java
als Programmiersprache suchen, finden Sie hier einige weitere Updates:
Java 8 hat die Lücke zwischen interface
- und abstract
-Klassen durch die Bereitstellung einer default
-Methode in gewissem Maße reduziert. Eine Schnittstelle hat keine Implementierung für eine Methode, die jetzt nicht mehr gültig ist.
Weitere Informationen finden Sie in dieser Dokumentation Seite .
Sehen Sie sich diese SE-Frage an, um Codebeispiele besser zu verstehen.
Wie hätte ich den Unterschied zwischen einer Interface- und einer Abstract-Klasse erklären sollen?
Einige wichtige Unterschiede:
In Form einer Tabelle:
Wie von Joe von javapapers angegeben :
1. Hauptunterschied ist, dass Methoden einer Java-Schnittstelle implizit abstrakt sind und keine Implementierungen haben können. Eine abstrakte Java-Klasse kann haben Instanzmethoden, die ein Standardverhalten implementieren.
2.Variablen, die in einer Java-Schnittstelle deklariert werden, 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 private, .__ haben. geschützt, etc ..
Die 4. Java-Schnittstelle sollte mit dem Schlüsselwort "implements" implementiert werden. Eine abstrakte Java-Klasse sollte mit dem Schlüsselwort "extend" erweitert werden.
5.An einer Schnittstelle kann nur eine andere Java-Schnittstelle erweitert werden. Eine abstrakte Klasse kann eine andere Java-Klasse erweitern und mehrere Java-Dateien implementieren Schnittstellen.
6.Eine Java-Klasse kann mehrere Schnittstellen implementieren, jedoch nur eine abstrakte Klasse erweitern.
7.Interface ist absolut abstrakt und kann nicht instanziiert werden. Eine abstrakte Java-Klasse kann auch nicht instanziiert werden, kann jedoch aufgerufen werden, wenn eine main () existiert.
8.Im Vergleich zu abstrakten Java-Klassen sind Java-Schnittstellen langsam, da sie eine zusätzliche Umleitung erfordern.
Der Hauptpunkt ist, dass:
Ich baue ein Gebäude mit 300 Stockwerken
Der Bauplan des Gebäudes Schnittstelle
Gebäude mit bis zu 200 Etagen gebaut - teilweise fertig gestellt --- abstrakt
Fertigstellung des Gebäudes - Beton
Schnittstelle
Abstrakt
Genommen von der DurgaJobs Website
Wenn Sie polymorphes Verhalten in einer Vererbungshierarchie bereitstellen möchten, verwenden Sie abstrakte Klassen.
Wenn Sie polymorphes Verhalten für Klassen wünschen, die völlig unabhängig voneinander sind, verwenden Sie eine Schnittstelle.
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 Ergebnis ergeben, dass Multiplikation und Division jedoch nicht gleich sind. Offensichtlich haben sie eine gute Beziehung, aber Sie sind beide unterschiedlich.
Ich werde die Hauptunterschiede aufzeigen, und der Rest wurde bereits erläutert:
Abstrakte Klassen sind nützlich, um eine Klassenhierarchie zu modellieren. Auf den ersten Blick jeder Anforderung ist uns teilweise klar, was genau gebaut werden soll, aber wir wissen was gebaut werden soll. Und so sind Ihre abstrakten Klassen Ihre Basisklassen.
Schnittstellen sind hilfreich, wenn andere Hierarchien oder Klassen wissen sollen, wozu ich fähig bin. Und wenn Sie sagen, dass ich zu etwas fähig bin, müssen Sie diese Fähigkeit haben. Schnittstellen kennzeichnen es als zwingend, dass eine Klasse dieselben Funktionalitäten implementiert.
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 "deklarieren" und nicht das Verhalten definieren, das die Klasse haben soll.
Mit einer abstrakten Klasse können Sie sowohl deklarieren (mit abstrakten Methoden) als auch (mit vollständigen Methodenimplementierungen) das Verhalten definieren, das die Klasse haben soll.
Mit einer regulären Klasse können Sie nur das Verhalten/die Aktionen definieren, die die Klasse haben soll, nicht deklarieren.
Eine letzte Sache,
In Java können Sie mehrere Schnittstellen implementieren, Sie können jedoch nur eine erweitern (abstrakte Klasse oder Klasse) ...
Dies bedeutet, dass die Vererbung von definiertem Verhalten nur auf eine Klasse beschränkt ist. Wenn Sie also eine Klasse mit gekapseltem Verhalten aus den Klassen A, B und C wünschen, müssen Sie Folgendes tun: Klasse A erweitert B, Klasse C erweitert A .. Es ist ein bisschen rund um die Mehrfachvererbung ...
Schnittstellen dagegen könnten Sie einfach tun: Schnittstelle C implementiert A, B
In der Tat unterstützt Java Mehrfachvererbung nur in "deklariertem Verhalten", dh Schnittstellen, und nur Einzelvererbung mit definiertem Verhalten. Es sei denn, Sie machen die Runde, die ich beschrieben habe.
Hoffentlich macht das Sinn.
Der Vergleich von Schnittstelle und abstrakter Klasse ist falsch. Es sollte stattdessen zwei weitere Vergleiche geben: 1) Schnittstelle vs. Klasse und 2) Zusammenfassung vs. Abschlussklasse .
Schnittstelle ist ein Vertrag zwischen zwei Objekten. Zum Beispiel bin ich ein Postbote und du bist ein Paket, das du liefern kannst. Ich erwarte, dass Sie Ihre Lieferadresse kennen. Wenn mir jemand ein Paket gibt, muss es seine Lieferadresse kennen:
interface Package {
String address();
}
Klasse ist eine Gruppe von Objekten, die den Vertrag einhalten. Ich bin zB eine Box aus der "Box" -Gruppe und gehorche dem vom Postboten geforderten Vertrag. Zur gleichen Zeit 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
}
}
Abstrakte Klasse ist eine Gruppe unvollständiger Objekte. Sie können nicht verwendet werden, weil sie einige Teile vermissen. Zum Beispiel bin ich eine abstrakte GPS-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 Bestandteile von Abschlussklassen sein.
Final class ist eine Gruppe von vollständigen Objekten, die verwendet werden können, aber nicht geändert werden können. Sie wissen genau, wie sie arbeiten und was zu tun ist. Zum Beispiel bin ich eine Box, die immer an die Adresse geht, die während des Baus 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 final. Eine solche Klasse kann vererbt und instanziiert werden. Ich glaube jedoch nicht, dass dies streng mit dem objektorientierten Paradigma übereinstimmt.
Auch hier ist der Vergleich von Schnittstellen mit abstrakten Klassen nicht korrekt.
Die Unterschiede sind kurz gesagt die folgenden:
Syntaktische Unterschiede zwischen Interface und Abstract Class :
In Interfaces jetzt:
public static
- unterstütztpublic abstract
- wird unterstütztpublic default
- wird unterstütztprivate static
- wird unterstütztprivate abstract
- Fehler beim Kompilierenprivate default
- Fehler beim Kompilierenprivate
- wird unterstützt
Der einzige Unterschied besteht darin, dass man an mehreren Vererbungen teilnehmen kann und andere nicht.
Die Definition einer Schnittstelle hat sich im Laufe der Zeit geändert. Denken Sie, eine Schnittstelle hat nur Methodendeklarationen und ist nur Verträge? Was ist mit statischen final-Variablen und wie sieht es mit Standarddefinitionen nach Java 8 aus?
Schnittstellen wurden in Java eingeführt, weil das Diamantenproblem mit mehrfacher Vererbung besteht. Dies ist genau das, was sie eigentlich vorhaben.
Schnittstellen sind die Konstrukte, die erstellt wurden, um das Problem der Mehrfachvererbung zu umgehen, und können abstrakte Methoden, Standarddefinitionen und statische letzte Variablen enthalten.
Schnittstelle: Drehen (Links abbiegen, Rechts abbiegen.)
Abstrakte Klasse: Rad.
Klasse: Lenkrad, vom Wheel abgeleitet, macht Interface Turn frei
Zum einen können Verhaltensweisen kategorisiert werden, die in einer Vielzahl von Dingen angeboten werden können, zum anderen wird eine Ontologie der Dinge modelliert.
Wenn Sie einige allgemeine Methoden haben, die von mehreren Klassen verwendet werden können, gehen Sie für abstrakte Klassen. Sonst, wenn die Klassen bestimmten Blaupausen für Schnittstellen folgen sollen.
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");
}
}
Im Folgenden finden Sie 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 Punkte in aller Kürze:
Die in der Java-Schnittstelle deklarierten Variablen sind standardmäßig final. Abstrakte Klassen können nicht endgültige Variablen haben.
Die in der Java-Schnittstelle deklarierten Variablen sind standardmäßig statisch. Abstrakte Klassen können nicht statische Variablen haben.
Mitglieder einer Java-Schnittstelle sind standardmäßig öffentlich. Eine abstrakte Java-Klasse kann die üblichen Arten von Klassenmitgliedern haben, wie private, protected usw.
Nicht wirklich die Antwort auf die ursprüngliche Frage, aber sobald Sie die Antwort auf den Unterschied zwischen ihnen gefunden haben, geben Sie das Wann-zu-Gebrauch-Problem an: Wann werden Schnittstellen oder abstrakte Klassen verwendet? Wann beides verwenden?
Ich habe nur ein begrenztes Wissen über OOP, aber Schnittstellen als Äquivalent eines Adjektivs in der Grammatik zu sehen, hat bisher für mich funktioniert (korrigieren Sie mich, wenn diese Methode falsch ist!). Zum Beispiel sind Schnittstellennamen wie Attribute oder Fähigkeiten, die Sie einer Klasse zuweisen können, und eine Klasse kann viele davon haben: ISerializable, ICountable, IList, ICacheable, IHappy, ...
Vererbung wird zu zwei Zwecken verwendet:
Um zuzulassen, dass ein Objekt übergeordnete Datenelemente und Methodenimplementierungen als seine eigenen betrachtet.
Um zuzulassen, dass ein Verweis auf ein Objekt eines Typs von einem Code verwendet wird, der einen Verweis auf ein Supertypobjekt erwartet.
In Sprachen/Frameworks, die eine verallgemeinerte Mehrfachvererbung unterstützen, ist es oft wenig erforderlich, einen Typ als "Schnittstelle" oder "abstrakte Klasse" zu klassifizieren. Populäre Sprachen und Frameworks erlauben es einem Typ jedoch, die Datenelemente oder Methodenimplementierungen eines anderen Typs als seine eigenen zu betrachten, obwohl sie zulassen, dass ein Typ eine beliebige Anzahl anderer Typen ersetzen kann.
Abstrakte Klassen können Datenelemente und Methodenimplementierungen enthalten, können jedoch nur von Klassen geerbt werden, die nicht von anderen Klassen erben. Schnittstellen setzen nahezu keine Einschränkungen für die Typen, die sie implementieren, können jedoch keine Datenelemente oder Methodenimplementierungen enthalten.
Es gibt Zeiten, in denen es nützlich ist, dass Typen für viele verschiedene Dinge substituierbar sind. Es gibt andere Situationen, in denen es nützlich ist, dass Objekte übergeordnete Datenelemente und Methodenimplementierungen als ihre eigenen betrachten. Durch die Unterscheidung zwischen Schnittstellen und abstrakten Klassen kann jede dieser Fähigkeiten in Fällen verwendet werden, in denen sie am relevantesten ist.
Schlüsselpunkte:
Vorteil:
details finden Sie hier ... http://pradeepatkari.wordpress.com/2014/11/20/interface-and-abstract-class-in-c-oops/
Sie können einen klaren Unterschied zwischen der abstrakten Klasse interface und feststellen.
Schnittstelle
Abstrakte Klasse
Die abstrakte Klasse enthält abstrakte und nicht abstrakte Methoden.
Zwingt den Benutzer nicht, alle Methoden zu implementieren, wenn die abstrakte Klasse __.
Enthält alle Arten von Variablen, einschließlich primitiv und nicht primitiv
Deklarieren Sie das abstrakte Schlüsselwort.
Methoden und Member einer abstrakten Klasse können mit einer beliebigen Sichtbarkeit definiert werden.
Eine Kindklasse kann nur eine Klasse erweitern (abstrakt oder konkret).
Der kürzeste Weg, um es zusammenzufassen, ist, dass eine interface
ist:
default
- und static
-Methoden; Es enthält zwar Definitionen (Methodensignaturen + Implementierungen) für default
- und static
-Methoden, jedoch nur Deklarationen (Methodensignaturen) für andere Methoden.interface
s implementieren und eine interface
kann von mehreren interface
s erben). Alle Variablen sind implizit konstant, unabhängig davon, ob sie als public static final
angegeben sind oder nicht. Alle Member sind implizit public
, unabhängig davon, ob sie als solche angegeben sind oder nicht.Inzwischen ist eine abstract
-Klasse:
abstract
-Methoden. Kann sowohl Deklarationen als auch Definitionen enthalten, wobei Deklarationen als abstract
markiert sind.protected
, private
oder als privates Paket (nicht angegeben) eingeschränkt werden.Oder, wenn wir alles auf einen einzigen Satz reduzieren wollen: Eine interface
ist das, was die implementierende Klasse hat, aber eine abstract
-Klasse ist die Unterklasse .
Unterschiede zwischen abstrakten Klassen und Schnittstellen für die reale Implementierung.
Interface : Es ist ein Schlüsselwort und wird verwendet, um die Vorlage oder den Blueprint eines Objekts zu definieren, und zwingt alle Unterklassen dazu, demselben Prototyp zu folgen, da bei der Implementierung alle Unterklassen frei implementiert werden können die Funktionalität gemäß ihrer Anforderung.
Einige andere Anwendungsfälle, bei denen die Schnittstelle verwendet werden sollte.
Die Kommunikation zwischen zwei externen Objekten (Einbindung von Drittanbietern in unsere Anwendung) erfolgt über Interface Hier arbeitet Interface als Vertrag.
Abstract Class: Abstract ist ein Schlüsselwort. Wenn dieses Schlüsselwort vor einer Klasse verwendet wird, wird es zu einer abstrakten Klasse. Es wird hauptsächlich verwendet, wenn die Vorlage sowie einige Standardfunktionen eines Objekts definiert werden müssen gefolgt von allen Unterklassen und auf diese Weise entfernt sie den redundanten Code und eine weitere Anwendungsfälle, in denen 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 Verwenden Sie die Funktionalität.
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 für eine 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");
}
}
Um eine einfache, aber klare Antwort zu geben, ist es hilfreich, den Kontext festzulegen: Sie verwenden beides, wenn Sie keine vollständigen Implementierungen bereitstellen möchten.
Der Hauptunterschied besteht darin, dass eine Schnittstelle überhaupt keine Implementierung hat (nur Methoden ohne Rumpf), während abstrakte Klassen Mitglieder und Methoden mit einem Rumpf haben können, d. H. Sie können teilweise implementiert werden.
Ich möchte noch einen weiteren Unterschied hinzufügen, der sinnvoll ist. Sie haben beispielsweise ein Framework mit Tausenden von Codezeilen. Wenn Sie nun eine neue Funktion im Code mithilfe einer Methode enhuUI () 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 einer Schnittstelle hinzufü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.
Per Definition können Schnittstellen keine Implementierung für Methoden haben, und Member-Variablen können nicht initialisiert werden.
Bei abstrakten Klassen können jedoch Methoden implementiert und Member-Variablen initialisiert werden.
Verwenden Sie abstrakte Klassen, wenn Sie Änderungen in Ihrem Vertrag erwarten, d. H. Sie müssen in Zukunft möglicherweise eine neue Methode hinzufügen.
Wenn Sie sich für die Verwendung einer Schnittstelle entscheiden, wird die Anwendung beim Ändern der Schnittstelle in Include-Schnittstelle beschädigt, wenn Sie die neue Schnittstellen-DLL sichern.
Um im Detail zu lesen, besuchen Sie Unterschied zwischen abstrakten Klassen und einer Schnittstelle
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 der Zugriffskennzeichen. Eine abstrakte Klasse kann Konstruktor- und andere konkrete (nicht abstarct-Methoden) -Methoden enthalten, aber keine Schnittstellen.
Eine Schnittstelle ist eine Blaupause/Vorlage von Methoden (z. B. ein Haus auf Papier wird angegeben (Schnittstellenhaus) und verschiedene Architekten verwenden ihre Ideen, um sie zu erstellen (die Klassen von Architekten, die die Hausschnittstelle implementieren). .__ Eine Sammlung abstrakter Methoden, Standardmethoden, statischer Methoden, abschließender Variablen und verschachtelter Klassen. Alle Mitglieder sind entweder endgültig oder öffentlich, geschützte und private Zugriffspezifizierer sind nicht zulässig. Es ist keine Objekterstellung zulässig. Eine Klasse Es muss gemacht werden, um die implementierende Schnittstelle zu verwenden und um die in der Schnittstelle deklarierte abstrakte Methode zu überschreiben. Eine Schnittstelle ist ein gutes Beispiel für lose Kopplung (dynamischer Polymorphismus/dynamische Bindung) Eine Schnittstelle implementiert Polymorphismus und Abstraktion Sagt, was zu tun ist, aber wie zu tun ist, wird von der implementierenden Klasse festgelegt. .__ Für z. B. gibt es eine Autofirma, und es möchte, dass einige Merkmale für alle Autos gleich sind, die es herstellt, so dass die Firma eine Schnittstelle Fahrzeug whi ch hat diese Funktionen und verschiedene Fahrzeugklassen (wie Maruti Suzkhi, Maruti 800) werden diese Funktionen (Funktionen) überschreiben.
Warum Schnittstelle, wenn wir bereits abstrakte Klassen haben? Java unterstützt nur mehrstufige und hierarchische Vererbung, aber mithilfe der Schnittstelle können wir mehrere Vererbung implementieren.
Viele Nachwuchsentwickler machen den Fehler, Schnittstellen, abstrakte und konkrete Klassen als geringfügige Variationen derselben Sache zu betrachten, und wählen aus rein technischen Gründen eine aus: Benötige 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 ist das Hauptproblem verborgen: "I". 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 völlig unterschiedliche Bedeutungen und Zwecke, obwohl sie aus technischer Sicht offensichtlich ähnlich sind.
Eine Schnittstelle definiert einen Vertrag die eine Implementierung für Sie erfüllen wird .
Eine abstrakte Klasse liefert ein Standardverhalten die Ihre Implementierung wiederverwenden kann.
Eine konkrete Klasse erledigt die eigentliche Arbeit auf ganz bestimmte Weise. Beispielsweise verwendet ein ArrayList
einen zusammenhängenden Speicherbereich, um eine Liste von Objekten auf kompakte Weise zu speichern. Dies bietet schnellen wahlfreien Zugriff, Iteration und direkte Änderungen, ist jedoch bei Einfügungen, Löschungen und gelegentlich schrecklich sogar Ergänzungen; In der Zwischenzeit speichert ein LinkedList
eine Liste von Objekten mit doppelt verknüpften Knoten, die stattdessen eine schnelle Iteration, direkte Änderungen und das Einfügen/Löschen/Hinzufügen bietet, aber beim wahllosen Zugriff furchtbar ist. Diese beiden Arten von Listen sind für unterschiedliche Anwendungsfälle optimiert, und es ist sehr wichtig, wie Sie sie verwenden. Wenn Sie versuchen, die Leistung aus einer Liste herauszuholen, mit der Sie intensiv interagieren, und wenn Sie die Art der Liste bestimmen, sollten Sie sorgfältig auswählen, welche Sie instanziieren.
Andererseits ist es Benutzern auf hoher Ebene einer Liste egal, wie sie tatsächlich implementiert wird, und sie sollten von diesen Details isoliert sein. Stellen wir uns vor, dass Java die List
-Schnittstelle nicht verfügbar machte, sondern nur eine konkrete List
-Klasse hatte, die genau das ist, was LinkedList
gerade ist. Alle Java - Entwickler hätten ihren Code an die Implementierungsdetails angepasst: Vermeiden Sie zufälligen Zugriff, fügen Sie einen Cache hinzu, um den Zugriff zu beschleunigen, oder implementieren Sie ArrayList
einfach neu, obwohl dies nicht mit allen kompatibel wäre Der andere Code, der tatsächlich nur mit List
funktioniert. 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, für ihre einzigen List
auf eine Array-Liste umzuschalten. Klasse zur Verfügung. Dies würde die Leistung jedes Java Programms auf der Welt beeinträchtigen, und die Leute wären darüber nicht glücklich. 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, ohne all die Eingeweide aufzudecken, die Programmierer dazu verleiten würden, ihren Code an die internen Details anzupassen, die sich bei zukünftigen Aktualisierungen ändern könnten .
Eine abstrakte Klasse befindet sich in der Mitte zwischen Interfaces und konkreten Klassen. Es soll Implementierungen dabei helfen, gemeinsamen oder langweiligen Code zu verwenden. Beispielsweise bietet AbstractCollection
grundlegende Implementierungen für isEmpty
basierend auf der Größe 0, contains
als Iteration und Vergleich, addAll
als Wiederholung add
, und so weiter. So können sich die Implementierungen auf die entscheidenden Teile konzentrieren, die sie voneinander unterscheiden: das Speichern und Abrufen von Daten.
Schnittstellen sind kohäsionsarm Gateways zwischen verschiedenen Codeteilen. Sie ermöglichen es Bibliotheken zu existieren und sich zu entwickeln, ohne jeden Bibliotheksbenutzer zu unterbrechen, wenn sich intern etwas ändert. Es heißt Application Programming Interface, nicht Application Programming Classes. In kleinerem Maßstab ermöglichen sie auch mehreren Entwicklern die erfolgreiche Zusammenarbeit in großen Projekten, indem sie verschiedene Module durch gut dokumentierte Schnittstellen trennen.
Abstrakte Klassen haben eine hohe Kohäsion Helfer, die bei der Implementierung einer Schnittstelle verwendet werden sollen, vorausgesetzt, dass ein gewisses Maß an Implementierungsdetails vorliegt. 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 auf who ses und bei einem SPI liegt der Fokus auf who implementiert it.
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 zur Definition eines SPI Schnittstellen verwendet werden, muss ein Anbieter bei jeder Änderung des Vertrags SPI eine neue Version freigeben. Wenn stattdessen abstrakte Klassen verwendet werden, können neue Methoden entweder als vorhandene abstrakte Methoden oder als leere throw not implemented exception
- Stubs definiert werden, sodass zumindest eine ältere Version einer Service-Implementierung weiterhin kompiliert und ausgeführt werden kann.
Obwohl in Java 8 Standardmethoden für Schnittstellen eingeführt wurden, wodurch die Grenze zwischen Schnittstellen und abstrakten Klassen noch unschärfer wird, können Implementierungen den Code nicht wiederverwenden, sondern erleichtern das Ändern von Schnittstellen, die beide als API dienen und als SPI (oder werden fälschlicherweise zum Definieren von SPIs anstelle von abstrakten Klassen verwendet).
Fazit: Umgekehrt wird oft fälschlicherweise verfahren: Verwenden Sie bei der Verwendung von immer die allgemeinste Klasse/Schnittstelle, 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 ausschneiden für dich. Verwenden Sie stattdessen List theList = new ArrayList
Oder sogar Collection theCollection = new ArrayList
, Wenn die Tatsache, dass es sich um eine Liste und keine andere Art von Sammlung handelt, keine Rolle spielt.
Eine einfache, aber effektive Erklärung der abstrakten Klasse und Schnittstelle auf php.net :
Eine Schnittstelle ist wie ein Protokoll. Es bezeichnet nicht das Verhalten des Objekts. Es gibt an, wie Ihr Code das Objekt zum Handeln auffordert. Eine Schnittstelle ist wie die englische Sprache: Die Definition einer Schnittstelle definiert, wie Ihr Code mit jedem Objekt kommuniziert, das diese Schnittstelle implementiert.
Eine Schnittstelle ist immer eine Vereinbarung oder ein Versprechen. Wenn eine Klasse sagt "Ich implementiere Schnittstelle Y", heißt es "Ich verspreche, die gleichen öffentlichen Methoden zu haben, die jedes Objekt mit Schnittstelle Y hat".
Auf der anderen Seite ist eine abstrakte Klasse wie eine teilweise gebaute Klasse. Es ist fast wie ein Dokument mit Leerzeichen zum Ausfüllen. Möglicherweise wird Englisch verwendet, aber das ist nicht so wichtig wie die Tatsache, dass ein Teil des Dokuments bereits geschrieben ist.
Eine abstrakte Klasse ist die Grundlage für ein anderes Objekt. Wenn eine Klasse sagt "Ich erweitere abstrakte Klasse Y", heißt es "Ich verwende einige Methoden oder Eigenschaften, die bereits in dieser anderen Klasse mit dem Namen Y definiert sind".
Betrachten Sie also folgendes PHP:
<?php class X implements Y { } // this is saying that "X" agrees to speak language "Y" with your code. class X extends Y { } // this is saying that "X" is going to complete the partial class "Y". ?>
Sie würden Ihre Klasse ein bestimmtes Interface implementieren lassen, wenn Sie eine Klasse verteilen würden, die von anderen Benutzern verwendet werden soll. Die Schnittstelle ist eine Vereinbarung, über eine bestimmte Gruppe öffentlicher Methoden für Ihre Klasse zu verfügen.
Sie würden Ihre Klasse eine abstrakte Klasse erweitern lassen, wenn Sie (oder eine andere Person) eine Klasse geschrieben haben, für die bereits einige Methoden geschrieben wurden, die Sie in Ihrer neuen Klasse verwenden möchten.
Diese Konzepte sind zwar leicht zu verwechseln, jedoch spezifisch verschieden und verschieden. Wenn Sie der einzige Benutzer einer Ihrer Klassen sind, müssen Sie keine Schnittstellen implementieren.
In einer Schnittstelle dürfen alle Methoden nur Definitionen sein, nicht einzelne sollten implementiert werden.
In einer abstrakten Klasse muss es jedoch eine abstrakte Methode mit nur Definition geben, aber andere Methoden können auch in der abstrakten Klasse mit Implementierung vorhanden sein.
in der Regel abstrakte Klasse für den Kern von etwas, aber Schnittstelle zum Anhängen von Peripheriegeräten.
wenn Sie einen Basistyp für ein Fahrzeug erstellen möchten, sollten Sie die abstrakte Klasse verwenden. Wenn Sie jedoch Funktionen oder Eigenschaften hinzufügen möchten, die nicht zum Basiskonzept des Fahrzeugs gehören, sollten Sie die Schnittstelle verwenden. Sie möchten beispielsweise die Funktion "ToJSON ()" hinzufügen .
die Schnittstelle hat einen breiten Abstraktionsbereich anstatt einer abstrakten Klasse. Sie können dies in Argumenten sehen. Schauen Sie sich dieses Beispiel an:
wenn Sie Fahrzeug als Argument verwenden, können Sie einfach einen der abgeleiteten Typen verwenden (Bus- oder Fahrzeugkategorie, nur Fahrzeugkategorie). Wenn Sie jedoch die IMoveable-Schnittstelle als Argument verwenden, haben Sie mehr Auswahlmöglichkeiten.
Schnittstellen sind im Allgemeinen die Klassen ohne Logik nur eine Signatur. Abstrakte Klassen dagegen sind logisch. Beide Support-Verträge als Interface-All-Methode sollten in der Kindklasse implementiert werden, abstrakt jedoch sollte nur die abstrakte Methode implementiert werden. Wann ist das Interface zu verwenden und wann abstrakt? Warum Interface verwenden?
class Circle {
protected $radius;
public function __construct($radius)
{
$this->radius = $radius
}
public function area()
{
return 3.14159 * pow(2,$this->radius); // simply pie.r2 (square);
}
}
//Our area calculator class would look like
class Areacalculator {
$protected $circle;
public function __construct(Circle $circle)
{
$this->circle = $circle;
}
public function areaCalculate()
{
return $circle->area(); //returns the circle area now
}
}
Wir würden es einfach tun
$areacalculator = new Areacalculator(new Circle(7));
Einige Tage später würden wir den Bereich von Rechteck, Quadrat, Viereck usw. benötigen. Wenn ja, müssen wir den Code jedes Mal ändern und überprüfen, ob es sich bei der Instanz um ein Quadrat, einen Kreis oder ein Rechteck handelt. Nun, was OCP sagt, ist CODE TO A INTERFACE NICHT IMPLEMENTIERUNG. Lösung wäre:
Interface Shape {
public function area(); //Defining contract for the classes
}
Class Square implements Shape {
$protected length;
public function __construct($length) {
//settter for length like we did on circle class
}
public function area()
{
//return l square for area of square
}
Class Rectangle implements Shape {
$protected length;
$protected breath;
public function __construct($length,$breath) {
//settter for length, breath like we did on circle,square class
}
public function area()
{
//return l*b for area of rectangle
}
}
Nun zum Flächenrechner
class Areacalculator {
$protected $shape;
public function __construct(Shape $shape)
{
$this->shape = $shape;
}
public function areaCalculate()
{
return $shape->area(); //returns the circle area now
}
}
$areacalculator = new Areacalculator(new Square(1));
$areacalculator->areaCalculate();
$areacalculator = new Areacalculator(new Rectangle(1,2));
$areacalculator->;areaCalculate();
Ist das nicht flexibler? Wenn wir ohne Schnittstelle codieren würden, würden wir die Instanz für jeden redundanten Formcode überprüfen.
Jetzt wann abstrakt verwenden?
Abstract Animal {
public function breathe(){
//all animals breathe inhaling o2 and exhaling co2
}
public function hungry() {
//every animals do feel hungry
}
abstract function communicate();
// different communication style some bark, some meow, human talks etc
}
Nun sollte abstract verwendet werden, wenn man keine Instanz dieser Klasse benötigt, die eine ähnliche Logik hat und den Vertrag benötigt.
Die allgemeine Idee von abstrakten Klassen und Iterfaces soll durch andere Klassen erweitert/implementiert werden (die nicht alleine erstellt werden können), die diese allgemeinen "Einstellungen" (eine Art Vorlage) verwenden, wodurch das Festlegen eines spezifischen allgemeinen Verhaltens für alle vereinfacht wird die Objekte, die es später erweitern.
Eine abstrakte Klasse verfügt über reguläre Methoden und abstrakte Methoden. Erweiterte Klassen können unset-Methoden enthalten, nachdem sie durch eine abstrakte Klasse erweitert wurden. Beim Festlegen abstrakter Methoden werden sie von den Klassen definiert, die sie später erweitern.
Schnittstellen haben die gleichen Eigenschaften wie eine abstrakte Klasse, enthalten jedoch nur abstrakte Methoden, die in anderen Klassen implementiert werden können (und es kann mehr als eine Schnittstelle implementiert werden). Dies führt zu einer dauerhafteren Definition von Methoden/statisch Variablen. Im Gegensatz zur abstrakten Klasse können Sie keine benutzerdefinierten "regulären" Methoden hinzufügen.
In der Praxis (Java) ist der Hauptunterschied zwischen der abstrakten Klasse und der Schnittstelle Die abstrakte Klasse kann den Status halten. Außer dem Status "Halten" können wir mit der Schnittstelle auch Ruheoperationen ausführen.
Wir haben verschiedene strukturelle/syntaktische Unterschiede zwischen Schnittstelle und abstrakter Klasse. Einige weitere Unterschiede sind
[1] Szenario-basierte Differenz :
Abstrakte Klassen werden in Szenarien verwendet, in denen der Benutzer auf das Erstellen von Objekten der übergeordneten Klasse beschränkt werden soll. Wir glauben, dass in Zukunft abstraktere Methoden hinzugefügt werden.
Die Schnittstelle muss verwendet werden, wenn wir sicher sind, dass keine abstraktere Methode mehr verfügbar ist. Dann wird nur eine Schnittstelle veröffentlicht.
[2] Begriffsunterschied :
"Müssen wir zukünftig abstraktere Methoden bereitstellen?", Wenn JA die Klasse abstrakt macht und wenn NEIN es die Schnittstelle bildet.
(Am besten geeignet und gültig bis Java 1.7)