im Gegensatz zu...? Schnittstellen haben viele Verwendungszwecke ...
Jason
6
Ich wünschte wirklich, die Leute würden keine Tags wie c # auf Posts setzen, die nicht c # -spezifisch sind. Es ist eine wirklich gute Frage, und ich hätte sie vielleicht verpasst, weil c # ein ignoriertes Tag ist.
Tyler Carter
Antworten:
170
Zwecke von Schnittstellen
Erstellen Sie lose gekoppelte Software
Support Design by Contract (ein Implementierer muss die gesamte Schnittstelle bereitstellen)
steckbare Software zulassen
Ermöglichen Sie die einfache Interaktion verschiedener Objekte
Implementierungsdetails von Klassen voreinander verbergen
Erleichterung der Wiederverwendung von Software
Analogie 1 : Ähnlich wie das US-Raumschiff können das russische Sojus-Raumschiff und das chinesische Shenzhou 5 an die Internationale Raumstation andocken, da sie dieselbe Docking-Schnittstelle implementieren. (Dies ist nur ein Beispiel - ich weiß nicht, ob es im wirklichen Leben wahr ist, aber lassen Sie uns unseren Unglauben aus Gründen eines Beispiels aussetzen.)
Analogie 2 : So können Sie verschiedene Computermonitore an Ihren Heimcomputer anschließen. Sie können einen Fernseher in Wandgröße daran anschließen, eine alte CRT (die dicke Art), einen 20-Zoll-Flachbildschirm oder eine Braille-Maschine, die Blinde durch Berühren "sehen" können. Es gibt Kompatibilität zwischen diesen verschiedenen / verschiedenen Geräten und Ihren Computer, weil sie sich alle auf Schnittstellenstandards einigen.
Details zu C # -Schnittstellen - Mit C # / OOP-Schnittstellen machen Sie dasselbe, jedoch in der unsichtbaren / virtuellen Welt.
Sie haben Recht mit Standardisierung , aber auch mit Flexibilität , Skalierbarkeit , Erweiterbarkeit , Wartbarkeit , Wiederverwendbarkeit , Testbarkeit und Leistung .
(Je häufiger Sie Softwareschnittstellen verwenden, desto besser werden diese "Modewörter" verstanden. Berücksichtigen Sie immer Schnittstellen in der realen Welt, weil sie uns gleich gut gemacht haben.)
Sie haben meine bevorzugte Verwendung von Schnittstellen ausgelassen: Testbarkeit. Wenn ich zwei Klassen habe, A & B und A.foo, ruft B.bar auf. Solange B eine Schnittstelle implementiert und in A "injiziert" werden kann, kann ich stattdessen eine Mock-, Fake- oder Stub-Klasse verwenden Dies ist besonders nützlich, wenn A.foo sein Verhalten basierend auf dem Rückgabewert von B.bar ändert. (Angenommen, B.bar gibt einen Bool zurück. A.foo hat möglicherweise eine if (B.bar) -Anweisung mit einer else-Klausel.) Durch die Verwendung einer Schnittstelle in B kann ich mockB, fakeB und / oder stubB erstellen, mit denen ich testen kann, was passiert, wenn B.bar true oder false zurückgibt.
Aridlehoover
@ Alan R-Testbarkeit hinzugefügt. Vielen Dank.
John K
1
Die akzeptierte Antwort ist TOP und es ist erfrischend zu sehen, dass das Konzept nicht verworfen wird, da die meisten Materialien für Framework-Designrichtlinien es nicht erklären oder verstehen. Wenn Sie Generika ernsthaft verwenden, weiß ich nicht, wie Sie jemals ohne sie ausgekommen sind.
Rama-Jka Toti
6
+1 fürstandardization, but also flexibility, scalability, extensibility, maintainability, reusability, testability and power.
Ravi
29
Eine Schnittstelle wird verwendet, um zu beschreiben, was eine implementierte Sache tun kann. Sie haben also die Möglichkeit, mehrere Objekte zu behandeln, die dieselbe Schnittstelle als Typ dieser Schnittstelle implementieren.
Zum Beispiel:
public interface IMyInterface{
public void DoFirst();
public int DoSecond();
}
public class A : IMyInterface{
//class has to implement DoFirst and DoSecond
public void DoFirst(){
Console.WriteLine("Blubb1");
}
public int DoSecond(){
Console.WriteLine("Blubb2");
return 2;
}
}
public class B : IMyInterface{
//class has to implement DoFirst and DoSecond
public void DoFirst(){
Console.WriteLine("Blibb1");
}
public int DoSecond(){
Console.WriteLine("Blibb2");
return 4;
}
}
Die Klassen implementieren die Schnittstelle auf verschiedene Arten. Sie können sie jedoch als IMyInterface verwenden. Zum Beispiel:
public static void DoMethodsInInterface(IMyInterface inter){
inter.DoFirst();
inter.DoSecond();
}
public static void main(){
DoMethodsInInterface(new A());
DoMethodsInInterface(new B());
//Or use it in a List
List<IMyInterface> interlist = new List<IMyInterface>();
interlist.Add(new A());
interlist.Add(new B());
foreach(IMyInterface inter in interlist){
inter.DoFirst();
}
}
Ich hoffe, dies macht ein bisschen klar, warum Schnittstellen nützlich sind.
Diese Frage wurde mit einer Frage verknüpft, in der gefragt wird, warum Schnittstellen verwendet werden sollen, anstatt nur Mitglieder zu haben, die die entsprechenden Funktionen usw. ausführen, und Ihre Antwort kommt der Beantwortung dieser Frage am nächsten. Wenn zwei nicht verwandte Klassen eine Methode haben Woozle, muss jeder Code, der einen Verweis auf eine der Klassen akzeptieren Woozlemöchte, wissen, mit welcher Klasse es sich handelt, und nur WoozleKlassen kennen, über die er Bescheid weiß. Im Gegensatz dazu , wenn beide Klassen implementieren IWoozler, dann Code, der jeder gegeben ist IWoozlerkann Woozlees ohne seine genaue Art zu kennen.
Superkatze
Diese Antwort macht es besser als jede andere, die ich gesehen habe. Es geht darum, was ein Objekt kann. Schnittstellen geben eine Reihe von Aktionen an, die sich auf das Objekt beziehen, ohne zu diktieren, was innerhalb dieser Aktionen geschieht, die offensichtlich objektspezifisch wären.
m12lrpv
5
Es ist für die Schnittstelle :), damit Sie zwischen Sachen Schnittstelle können, ist es nützlich, wenn Sie haben
mehrere Implementierungen des gleichen Materials
Wenn Sie eine Schnittstelle auf mehrere verschiedene Klassen anwenden, weil Sie eine Art Konvention benötigen, dass diese Klassen in der Lage sind, einige Dinge zu tun oder einige Funktionen zu haben
Sie helfen Ihnen im Grunde dabei, die Implementierungsdetails Ihrer Klasse auszublenden, sodass eine aufrufende Klasse keine Abhängigkeit von dieser Implementierung hat. Daher können Sie mithilfe von Schnittstellen die Implementierung ändern, ohne die aufrufende Klasse zu ändern. Dies alles begrenzt wiederum die Komplexität Ihres Codes und erleichtert die langfristige Wartung .
Als ich anfing, Schnittstellen zu verstehen, wurden sie mir als "Vertrag, der eine Beschreibung Ihrer Klasse enthält" erklärt. Ich bin mir nicht sicher, ob das Ihnen helfen wird, aber wenn Sie an eine Schnittstelle für ein Auto denken, können Sie sagen, dass es fährt , bricht und dreht . Solange ich von Punkt A nach Punkt B komme, muss ich nicht wirklich wissen, wie diese Funktionen implementiert sind.
Der Hauptgrund, warum die Schnittstellen in Sprachen wie C # / Java verwendet werden, liegt darin, dass diese Sprachen keine Mehrfachvererbung (Klassenvererbung) unterstützen (siehe Was ist das genaue Problem bei Mehrfachvererbung? ).
Es ist jedoch eine Mehrfachimplementierung (Schnittstellenimplementierung) zulässig, sodass Klassen auf unterschiedliche Weise verwendet werden können.
Schnittstellen in verwalteten Sprachen sind KEIN Ersatz für Mehrfachvererbung. Und selbst in Sprachen, die Mehrfachvererbung unterstützen, ist das Konzept einer Schnittstelle ohne Implementierung relavant und nützlich. (Siehe Abhängigkeitsinjektion.)
Aridlehoover
1
-1 nicht sehr gut durchdacht, oder verstehen Sie C # oder Java wirklich nicht?
John Saunders
Ich möchte nur sagen, dass in C ++ reine abstrakte Klassen anstelle von Schnittstellen verwendet werden können. Die meisten Dinge, die Sie in Java / C # mit Schnittstellen tun können, können Sie in C ++ mit reinen abstrakten Klassen tun. Wenn Sie in C ++ möchten, dass eine Klasse mehrere Verhaltensweisen aufweist, erben Sie mehrere reine abstrakte Klassen. In Java / C # ist dies jedoch nicht möglich. Ich sage nicht, dass Schnittstellen nicht "nützlich" sind, ich sage mehr als das: Sprachen wie Java & C # wären ohne die Vererbung mehrerer Schnittstellen keine objektorientierten Programmiersprachen. (Sie erlauben keine Vererbung mehrerer Klassen oder Mixins)
Catalin DICU
1
+1 Dies ist im Wesentlichen das, was durch die Erfahrung von C # und Java auf die harte Tour entdeckt wurde. Wenn Sie versuchen zu vereinfachen, indem Sie Mehrfachvererbung vermeiden, schaffen Sie nur an anderer Stelle Komplexität. Aufgrund des Fehlens eines einheitlichen zugrunde liegenden Ansatzes ist die Komplexität geringer. Siehe die Anmerkung von Krzystof Cwalina in C # Programming Language 3rd Edition , 1.9 Interfaces, die genau dies sagt. Derzeit gibt es in C # und Java noch ungelöste Probleme, die einfache Lösungen hätten, wenn die mehrfache Vererbung von Klassen zulässig wäre.
Daniel Earwicker
-1 Vererbung und Schnittstellen sind wirklich sehr unterschiedlich.
Kenny
2
Schnittstellen sind etwas umständlich. Sie unterstützen das vertragliche Design, indem sie glauben, dass derselbe Name und die implementierte Schnittstelle dasselbe Verhalten bedeuten. Dies funktioniert nur dank der API-Dokumentation, es muss von Menschen überprüft werden. Das macht Schnittstellen zu schwach. Eine Möglichkeit, dies zu umgehen, könnten formale Spezifikationen sein. Andererseits sind Schnittstellen zu stark und zu streng. Sie können keine Schnittstellen entwickeln, die häufig der Wiederverwendung im Wege stehen. Dies wird durch Protokolle gelöst - Mechanismen in dynamischen Sprachen, die Nachrichten senden (Aufrufmethoden). Wenn diese Nachricht vom Empfänger nicht unterstützt wird, wird ein Standardrückruf aufgerufen. Konkrete Protokolle mit Einschränkungen wären imho besser.
Hier sind ein Client und ein Server beteiligt. Nehmen wir an, sie sind durch das Internet physisch getrennt. Der Client ruft eine Methode auf, deren tatsächliche Ausführung auf dem Server erfolgt. Aus Sicht des Clients weiß der Client nichts über das Objekt auf dem Server, das die Ausführung ausführt. Es weiß jedoch, welche Methode aufzurufen ist. Denn beim Erstellen des Client-Programms sind wir nur einer Schnittstelle (oder einem Vertrag) ausgesetzt. Wir sind nicht dem gesamten Objekt ausgesetzt, das tatsächlich auf dem Server lebt. Versuchen Sie, einige Demo-Apps in .net Remoting zu erstellen, und Sie werden den Rest herausfinden. Viel Spaß beim Programmieren.
Einige Sprachen implementieren polymorphe Methodenaufrufe mithilfe von vtables und verwerfen die meisten Typinformationen, sodass es schwierig ist, keine Schnittstellen zu definieren.
Manchmal verwenden wir einfach Schnittstellen, weil das Sprachdesign dies erfordert.
Wenn Sie mit einer Schnittstelle beginnen, können Sie einen Proxy implementieren und so das verzögerte Laden oder Durchführen einiger Überprüfungen beim Aufrufen der Methoden einer konkreten Implementierung ermöglichen.
Die Schnittstelle bietet einen modalen Prototyp, der nur die Deklaration der Funktionalität eines bestimmten Verhaltens enthält.
und wenn Sie dieses Verhalten in der Klasse implementieren möchten, müssen Sie diese Schnittstelle in der Klasse implementieren, dann hat die Klasse diese Verhaltensfunktionalität oder sie kann mehrere Verhaltensweisen haben.
weil Klasse mehrere Schnittstellen implementieren kann.
Wenn jemand wie ich ist und durch Vorbild und Handeln lernt, anstatt nur zu erklären, hier ist ein Code ...
Ich fand diese Implementierung eines neuronalen Netzwerks in C #, einschließlich des Projektdownloads, bei dem Schnittstellen auf elegante und nützliche Weise verwendet werden:
Antworten:
Zwecke von Schnittstellen
Analogie 1 : Ähnlich wie das US-Raumschiff können das russische Sojus-Raumschiff und das chinesische Shenzhou 5 an die Internationale Raumstation andocken, da sie dieselbe Docking-Schnittstelle implementieren. (Dies ist nur ein Beispiel - ich weiß nicht, ob es im wirklichen Leben wahr ist, aber lassen Sie uns unseren Unglauben aus Gründen eines Beispiels aussetzen.)
Analogie 2 : So können Sie verschiedene Computermonitore an Ihren Heimcomputer anschließen. Sie können einen Fernseher in Wandgröße daran anschließen, eine alte CRT (die dicke Art), einen 20-Zoll-Flachbildschirm oder eine Braille-Maschine, die Blinde durch Berühren "sehen" können. Es gibt Kompatibilität zwischen diesen verschiedenen / verschiedenen Geräten und Ihren Computer, weil sie sich alle auf Schnittstellenstandards einigen.
Details zu C # -Schnittstellen - Mit C # / OOP-Schnittstellen machen Sie dasselbe, jedoch in der unsichtbaren / virtuellen Welt.
Sie haben Recht mit Standardisierung , aber auch mit Flexibilität , Skalierbarkeit , Erweiterbarkeit , Wartbarkeit , Wiederverwendbarkeit , Testbarkeit und Leistung .
(Je häufiger Sie Softwareschnittstellen verwenden, desto besser werden diese "Modewörter" verstanden. Berücksichtigen Sie immer Schnittstellen in der realen Welt, weil sie uns gleich gut gemacht haben.)
quelle
standardization, but also flexibility, scalability, extensibility, maintainability, reusability, testability and power.
Eine Schnittstelle wird verwendet, um zu beschreiben, was eine implementierte Sache tun kann. Sie haben also die Möglichkeit, mehrere Objekte zu behandeln, die dieselbe Schnittstelle als Typ dieser Schnittstelle implementieren.
Zum Beispiel:
Die Klassen implementieren die Schnittstelle auf verschiedene Arten. Sie können sie jedoch als IMyInterface verwenden. Zum Beispiel:
Ich hoffe, dies macht ein bisschen klar, warum Schnittstellen nützlich sind.
quelle
Woozle
, muss jeder Code, der einen Verweis auf eine der Klassen akzeptierenWoozle
möchte, wissen, mit welcher Klasse es sich handelt, und nurWoozle
Klassen kennen, über die er Bescheid weiß. Im Gegensatz dazu , wenn beide Klassen implementierenIWoozler
, dann Code, der jeder gegeben istIWoozler
kannWoozle
es ohne seine genaue Art zu kennen.Es ist für die Schnittstelle :), damit Sie zwischen Sachen Schnittstelle können, ist es nützlich, wenn Sie haben
quelle
Hier ist die Ansicht auf hoher Ebene ...
Schnittstellen spielen eine große Rolle im Konzept des Versteckens von Informationen .
Sie helfen Ihnen im Grunde dabei, die Implementierungsdetails Ihrer Klasse auszublenden, sodass eine aufrufende Klasse keine Abhängigkeit von dieser Implementierung hat. Daher können Sie mithilfe von Schnittstellen die Implementierung ändern, ohne die aufrufende Klasse zu ändern. Dies alles begrenzt wiederum die Komplexität Ihres Codes und erleichtert die langfristige Wartung .
Als ich anfing, Schnittstellen zu verstehen, wurden sie mir als "Vertrag, der eine Beschreibung Ihrer Klasse enthält" erklärt. Ich bin mir nicht sicher, ob das Ihnen helfen wird, aber wenn Sie an eine Schnittstelle für ein Auto denken, können Sie sagen, dass es fährt , bricht und dreht . Solange ich von Punkt A nach Punkt B komme, muss ich nicht wirklich wissen, wie diese Funktionen implementiert sind.
quelle
Der Hauptgrund, warum die Schnittstellen in Sprachen wie C # / Java verwendet werden, liegt darin, dass diese Sprachen keine Mehrfachvererbung (Klassenvererbung) unterstützen (siehe Was ist das genaue Problem bei Mehrfachvererbung? ).
Es ist jedoch eine Mehrfachimplementierung (Schnittstellenimplementierung) zulässig, sodass Klassen auf unterschiedliche Weise verwendet werden können.
quelle
Schnittstellen sind etwas umständlich. Sie unterstützen das vertragliche Design, indem sie glauben, dass derselbe Name und die implementierte Schnittstelle dasselbe Verhalten bedeuten. Dies funktioniert nur dank der API-Dokumentation, es muss von Menschen überprüft werden. Das macht Schnittstellen zu schwach. Eine Möglichkeit, dies zu umgehen, könnten formale Spezifikationen sein. Andererseits sind Schnittstellen zu stark und zu streng. Sie können keine Schnittstellen entwickeln, die häufig der Wiederverwendung im Wege stehen. Dies wird durch Protokolle gelöst - Mechanismen in dynamischen Sprachen, die Nachrichten senden (Aufrufmethoden). Wenn diese Nachricht vom Empfänger nicht unterstützt wird, wird ein Standardrückruf aufgerufen. Konkrete Protokolle mit Einschränkungen wären imho besser.
quelle
Denken Sie an Remoting ...
Hier sind ein Client und ein Server beteiligt. Nehmen wir an, sie sind durch das Internet physisch getrennt. Der Client ruft eine Methode auf, deren tatsächliche Ausführung auf dem Server erfolgt. Aus Sicht des Clients weiß der Client nichts über das Objekt auf dem Server, das die Ausführung ausführt. Es weiß jedoch, welche Methode aufzurufen ist. Denn beim Erstellen des Client-Programms sind wir nur einer Schnittstelle (oder einem Vertrag) ausgesetzt. Wir sind nicht dem gesamten Objekt ausgesetzt, das tatsächlich auf dem Server lebt. Versuchen Sie, einige Demo-Apps in .net Remoting zu erstellen, und Sie werden den Rest herausfinden. Viel Spaß beim Programmieren.
quelle
Einige Sprachen implementieren polymorphe Methodenaufrufe mithilfe von vtables und verwerfen die meisten Typinformationen, sodass es schwierig ist, keine Schnittstellen zu definieren.
Manchmal verwenden wir einfach Schnittstellen, weil das Sprachdesign dies erfordert.
quelle
Wenn Sie mit einer Schnittstelle beginnen, können Sie einen Proxy implementieren und so das verzögerte Laden oder Durchführen einiger Überprüfungen beim Aufrufen der Methoden einer konkreten Implementierung ermöglichen.
quelle
Die Schnittstelle trennt den Datentyp von der Implementierungslogik.
quelle
Die Schnittstelle bietet einen modalen Prototyp, der nur die Deklaration der Funktionalität eines bestimmten Verhaltens enthält.
und wenn Sie dieses Verhalten in der Klasse implementieren möchten, müssen Sie diese Schnittstelle in der Klasse implementieren, dann hat die Klasse diese Verhaltensfunktionalität oder sie kann mehrere Verhaltensweisen haben.
weil Klasse mehrere Schnittstellen implementieren kann.
quelle
Wenn jemand wie ich ist und durch Vorbild und Handeln lernt, anstatt nur zu erklären, hier ist ein Code ...
Ich fand diese Implementierung eines neuronalen Netzwerks in C #, einschließlich des Projektdownloads, bei dem Schnittstellen auf elegante und nützliche Weise verwendet werden:
http://www.c-sharpcorner.com/UploadFile/rmcochran/AI_OOP_NeuralNet06192006090112AM/AI_OOP_NeuralNet.aspx
quelle