Ok, ein Freund von mir geht hin und her, was "Schnittstelle" in der Programmierung bedeutet.
Was ist die beste Beschreibung einer "Schnittstelle".
Für mich ist eine Schnittstelle eine Blaupause einer Klasse. Ist dies die beste Definition?
Ok, ein Freund von mir geht hin und her, was "Schnittstelle" in der Programmierung bedeutet.
Was ist die beste Beschreibung einer "Schnittstelle".
Für mich ist eine Schnittstelle eine Blaupause einer Klasse. Ist dies die beste Definition?
Antworten:
Eine Schnittstelle ist einer der überlasteten und verwirrenden Begriffe in der Entwicklung.
Es ist eigentlich ein Konzept der Abstraktion und Kapselung. Für eine gegebene "Box" ist es die "Eingänge" und "Ausgänge" dieser Box deklariert . In der Welt der Software bedeutet dies normalerweise die Operationen, die auf der Box aufgerufen werden können (zusammen mit Argumenten), und in einigen Fällen die Rückgabetypen dieser Operationen.
Was es nicht tut, ist zu definieren, wie die Semantik dieser Operationen ist, obwohl es üblich (und sehr bewährte Verfahren) ist, sie in der Nähe der Deklaration zu dokumentieren (z. B. über Kommentare) oder gute Namenskonventionen auszuwählen. Es gibt jedoch keine Garantie dafür, dass diese Absichten befolgt werden.
Hier ist eine Analogie: Sehen Sie sich Ihren Fernseher an, wenn er ausgeschaltet ist. Die Benutzeroberfläche besteht aus den Tasten, den verschiedenen Steckern und dem Bildschirm. Seine Semantik und sein Verhalten sind, dass es Eingaben (z. B. Kabelprogrammierung) und Ausgänge (Anzeige auf dem Bildschirm, Ton usw.) hat. Wenn Sie sich jedoch einen Fernseher ansehen, der nicht angeschlossen ist, projizieren Sie Ihre erwartete Semantik in eine Schnittstelle. Nach allem, was Sie wissen, kann der Fernseher beim Anschließen explodieren. Aufgrund seiner "Schnittstelle" können Sie jedoch davon ausgehen, dass kein Kaffee zubereitet wird, da er keinen Wassereinlass hat.
Bei der objektorientierten Programmierung definiert eine Schnittstelle im Allgemeinen die Gruppe von Methoden (oder Nachrichten), auf die eine Instanz einer Klasse mit dieser Schnittstelle reagieren kann.
Was zur Verwirrung beiträgt, ist, dass es in einigen Sprachen wie Java eine tatsächliche Schnittstelle zu seiner sprachspezifischen Semantik gibt. In Java handelt es sich beispielsweise um eine Reihe von Methodendeklarationen ohne Implementierung, aber eine Schnittstelle entspricht auch einem Typ und befolgt verschiedene Typisierungsregeln.
In anderen Sprachen wie C ++ haben Sie keine Schnittstellen. Eine Klasse selbst definiert Methoden, aber Sie können sich die Schnittstelle der Klasse als Deklarationen der nicht privaten Methoden vorstellen. Aufgrund der Kompilierung von C ++ erhalten Sie Header-Dateien, in denen Sie die "Schnittstelle" der Klasse ohne tatsächliche Implementierung haben könnten. Sie können auch Java-Schnittstellen mit abstrakten Klassen mit rein virtuellen Funktionen usw. nachahmen.
Eine Schnittstelle ist mit Sicherheit keine Blaupause für eine Klasse. Eine Blaupause ist nach einer Definition ein "detaillierter Aktionsplan". Eine Schnittstelle verspricht nichts über eine Aktion! Die Quelle der Verwirrung ist, dass in den meisten Sprachen, wenn Sie einen Schnittstellentyp haben, der eine Reihe von Methoden definiert, die Klasse, die ihn implementiert, dieselben Methoden "wiederholt" (aber eine Definition bereitstellt), sodass die Schnittstelle wie ein Skelett oder ein Skelett aussieht Umriss der Klasse.
Betrachten Sie die folgende Situation:
Sie befinden sich mitten in einem großen, leeren Raum, als ein Zombie Sie plötzlich angreift.
Du hast keine Waffe.
Zum Glück steht ein lebender Mitmensch in der Tür des Raumes.
"Schnell!" du schreist ihn an "Wirf mir etwas, mit dem ich den Zombie schlagen kann!"
Bedenken
Sie nun: Sie haben nicht genau angegeben (und es interessiert Sie auch nicht), was Ihr Freund werfen möchte .
... aber es spielt keine Rolle, solange:
Es ist etwas , das kann geworfen werden (er kann das Sofa nicht werfen)
Es ist etwas, das Sie ergreifen können (Hoffen wir, dass er keine Shuriken geworfen hat)
Es ist etwas, mit dem Sie das Gehirn des Zombies schlagen können (das schließt Kissen und dergleichen aus).
Es spielt keine Rolle, ob Sie einen Baseballschläger oder einen Hammer bekommen -
solange dies Ihre drei Bedingungen erfüllt, sind Sie gut.
Etwas zusammenfassen:
Wenn Sie eine Schnittstelle schreiben, sagen Sie im Grunde: "Ich brauche etwas, das ..."
Interface ist ein Vertrag, den Sie einhalten oder einhalten sollten, je nachdem, ob Sie Implementierer oder Benutzer sind.
Ich denke nicht, dass "Blaupause" ein gutes Wort ist. Eine Blaupause zeigt Ihnen, wie Sie etwas bauen. Eine Schnittstelle vermeidet ausdrücklich, Ihnen zu sagen, wie Sie etwas erstellen sollen.
Eine Schnittstelle definiert, wie Sie mit einer Klasse interagieren können, dh welche Methoden sie unterstützt.
Für mich ist eine Schnittstelle eine Blaupause einer Klasse. Ist dies die beste Definition?
Nein. Eine Blaupause enthält normalerweise die Einbauten. Bei einer Schnittstelle geht es jedoch nur um das, was außerhalb einer Klasse sichtbar ist ... oder genauer gesagt um eine Klassenfamilie, die die Schnittstelle implementiert.
Die Schnittstelle besteht aus den Signaturen von Methoden und Werten von Konstanten sowie einem (normalerweise informellen) "Verhaltensvertrag" zwischen Klassen, die die Schnittstelle implementieren, und anderen, die sie verwenden.
In der Programmierung definiert eine Schnittstelle das Verhalten eines Objekts, gibt das Verhalten jedoch nicht an. Es ist ein Vertrag, der garantiert, dass eine bestimmte Klasse etwas tun kann.
Betrachten Sie diesen Teil des C # -Codes hier:
using System;
public interface IGenerate
{
int Generate();
}
// Dependencies
public class KnownNumber : IGenerate
{
public int Generate()
{
return 5;
}
}
public class SecretNumber : IGenerate
{
public int Generate()
{
return new Random().Next(0, 10);
}
}
// What you care about
class Game
{
public Game(IGenerate generator)
{
Console.WriteLine(generator.Generate())
}
}
new Game(new SecretNumber());
new Game(new KnownNumber());
Die Spielklasse benötigt eine Geheimnummer. Zum Testen möchten Sie die als Geheimnummer verwendete Nummer injizieren (dieses Prinzip wird als Inversion of Control bezeichnet).
Die Spielklasse möchte "aufgeschlossen" sein, was die Zufallszahl tatsächlich erzeugt, und fragt daher in ihrem Konstruktor nach "allem, was eine Generierungsmethode hat".
Zunächst gibt die Schnittstelle an, welche Operationen ein Objekt bereitstellen wird. Es enthält nur, wie es aussieht, aber es wird keine tatsächliche Implementierung angegeben. Dies ist nur die Signatur der Methode. Herkömmlicherweise wird in C # -Schnittstellen ein I vorangestellt. Die Klassen implementieren jetzt die IGenerate-Schnittstelle. Dies bedeutet, dass der Compiler sicherstellt, dass beide eine Methode haben, die ein int zurückgibt und aufgerufen wirdGenerate
. Das Spiel heißt jetzt zwei verschiedene Objekte, von denen jedes die richtige Schnittstelle implementiert. Andere Klassen würden beim Erstellen des Codes einen Fehler erzeugen.
Hier ist mir die von Ihnen verwendete Blaupausenanalogie aufgefallen:
Eine Klasse wird üblicherweise als Blaupause für ein Objekt angesehen. Eine Schnittstelle gibt etwas an, das eine Klasse tun muss, sodass man argumentieren könnte, dass es sich tatsächlich nur um eine Blaupause für eine Klasse handelt. Da eine Klasse jedoch nicht unbedingt eine Schnittstelle benötigt, würde ich argumentieren, dass diese Metapher nicht funktioniert. Stellen Sie sich eine Schnittstelle als Vertrag vor. Die Klasse, die es "unterschreibt", ist gesetzlich verpflichtet (von der Compiler-Polizei durchgesetzt), die Vertragsbedingungen einzuhalten. Dies bedeutet, dass es tun muss, was in der Schnittstelle angegeben ist.
Dies alles ist auf die statische Typisierung einiger OO-Sprachen zurückzuführen, wie dies bei Java oder C # der Fall ist. In Python wird dagegen ein anderer Mechanismus verwendet:
import random
# Dependencies
class KnownNumber(object):
def generate(self):
return 5
class SecretNumber(object):
def generate(self):
return random.randint(0,10)
# What you care about
class SecretGame(object):
def __init__(self, number_generator):
number = number_generator.generate()
print number
Hier implementiert keine der Klassen eine Schnittstelle. Python kümmert sich nicht darum, da die SecretGame
Klasse nur versucht, das übergebene Objekt aufzurufen. Wenn das Objekt eine generate () -Methode hat, ist alles in Ordnung. Wenn nicht: KAPUTT! Dieser Fehler wird nicht zur Kompilierungszeit, sondern zur Laufzeit angezeigt, möglicherweise wenn Ihr Programm bereits bereitgestellt ist und ausgeführt wird. C # würde Sie benachrichtigen, bevor Sie dem nahe kommen.
Der Grund, warum dieser Mechanismus verwendet wird, ist naiv ausgedrückt, weil in OO-Sprachen Funktionen natürlich keine erstklassigen Bürger sind. Wie Sie sehen können KnownNumber
und SecretNumber
nur die Funktionen enthalten, um eine Zahl zu generieren. Den Unterricht braucht man eigentlich gar nicht. In Python könnte man sie daher einfach wegwerfen und die Funktionen selbst auswählen:
# OO Approach
SecretGame(SecretNumber())
SecretGame(KnownNumber())
# Functional Approach
# Dependencies
class SecretGame(object):
def __init__(self, generate):
number = generate()
print number
SecretGame(lambda: random.randint(0,10))
SecretGame(lambda: 5)
Ein Lambda ist nur eine Funktion, die als "in line, as you go" deklariert wurde. Ein Delegat ist in C # genauso:
class Game
{
public Game(Func<int> generate)
{
Console.WriteLine(generate())
}
}
new Game(() => 5);
new Game(() => new Random().Next(0, 10));
Randnotiz: Die letzteren Beispiele waren bis Java 7 nicht so möglich. Dort waren Schnittstellen Ihre einzige Möglichkeit, dieses Verhalten zu spezifizieren. In Java 8 wurden jedoch Lambda-Ausdrücke eingeführt, sodass das C # -Beispiel sehr einfach in Java konvertiert werden kann ( Func<int>
wird java.util.function.IntSupplier
und =>
wird ->
).
Technisch würde ich eine Schnittstelle als eine Reihe von Möglichkeiten beschreiben (Methoden, Eigenschaften, Zugriffsmethoden ... das Vokabular hängt von der Sprache ab, die Sie verwenden), um mit einem Objekt zu interagieren. Wenn ein Objekt eine Schnittstelle unterstützt / implementiert, können Sie alle in der Schnittstelle angegebenen Möglichkeiten verwenden, um mit diesem Objekt zu interagieren.
Semantisch könnte eine Schnittstelle auch Konventionen darüber enthalten, was Sie tun oder nicht tun können (z. B. die Reihenfolge, in der Sie die Methoden aufrufen können) und was Sie im Gegenzug über den Zustand des Objekts annehmen können, wenn Sie so interagieren weit.
Persönlich sehe ich eine Oberfläche wie eine Vorlage. Wenn eine Schnittstelle die Definition für die Methoden foo () und bar () enthält, wissen Sie, dass jede Klasse, die diese Schnittstelle verwendet, die Methoden foo () und bar () hat.
Betrachten wir einen Mann (Benutzer oder ein Objekt), der etwas Arbeit erledigen möchte. Er wird einen Mittelsmann (Schnittstelle) kontaktieren, der einen Vertrag mit den Unternehmen hat (reale Objekte, die mit implementierten Klassen erstellt wurden). Er wird nur wenige Arten von Arbeiten definieren, die von den Unternehmen umgesetzt und Ergebnisse erzielt werden. Jedes Unternehmen wird die Arbeit auf seine eigene Weise umsetzen, aber das Ergebnis wird das gleiche sein. Auf diese Weise erledigt der Benutzer seine Arbeit über eine einzige Oberfläche. Ich denke, Interface wird als sichtbarer Teil der Systeme mit wenigen Befehlen fungieren, die intern von den implementierenden inneren Subsystemen definiert werden.
Eine Schnittstelle trennt Operationen an einer Klasse von der Implementierung innerhalb. Daher können einige Implementierungen viele Schnittstellen bereitstellen.
Die Leute würden es normalerweise als "Vertrag" für das beschreiben, was in den Methoden der Klasse verfügbar sein muss.
Es ist absolut keine Blaupause, da dies auch die Implementierung bestimmen würde. Eine vollständige Klassendefinition könnte als Blaupause bezeichnet werden.
Eine Schnittstelle definiert, was eine Klasse, die von ihr erbt, implementieren muss. Auf diese Weise können mehrere Klassen von einer Schnittstelle erben, und aufgrund dieser Vererbung können Sie dies
Weitere Informationen finden Sie unter http://msdn.microsoft.com/en-us/library/ms173156.aspx
Meiner Meinung nach hat die Schnittstelle eine breitere Bedeutung als die in Java übliche. Ich würde "Schnittstelle" als eine Reihe verfügbarer Operationen mit einigen allgemeinen Funktionen definieren, die das Steuern / Überwachen eines Moduls ermöglichen.
In dieser Definition versuche ich, sowohl programmatische Schnittstellen, bei denen der Client ein Modul ist, als auch menschliche Schnittstellen (z. B. GUI) abzudecken.
Wie andere bereits sagten, hat eine Schnittstelle immer einen Vertrag in Bezug auf Ein- und Ausgänge. Die Schnittstelle verspricht nichts über das "Wie" der Operationen; Es garantiert nur einige Eigenschaften des Ergebnisses in Anbetracht des aktuellen Status, der ausgewählten Operation und ihrer Parameter.
Wie oben sind Synonyme von "Vertrag" und "Protokoll" angemessen.
Die Schnittstelle enthält die Methoden und Eigenschaften, von denen Sie erwarten können, dass sie von einer Klasse verfügbar gemacht werden.
Wenn eine Klasse Cheetos Bag
die Chip Bag
Schnittstelle implementiert , sollten Sie erwarten Cheetos Bag
, dass sich a genau wie jede andere verhält Chip Bag
. (Das heißt, legen Sie die .attemptToOpenWithoutSpillingEverywhere()
Methode usw. offen .)
Konventionelle Definition - Eine Schnittstelle ist ein Vertrag, der die Methoden angibt, die von der Klasse implementiert werden müssen, die sie implementiert.
Die Definition der Schnittstelle hat sich im Laufe der Zeit geändert. Denken Sie, dass Interface nur Methodendeklarationen hat? Was ist mit statischen endgültigen Variablen und was ist mit Standarddefinitionen nach Java 5?
Schnittstellen wurden aufgrund des Diamond-Problems mit mehrfacher Vererbung 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.
Eine Grenze, über die zwei Systeme kommunizieren.
Durch Schnittstellen erreichen einige OO-Sprachen einen Ad-hoc-Polymorphismus . Ad-hoc-Polymorphismus ist einfach eine Funktion mit demselben Namen, die für verschiedene Typen verwendet wird.
Kurz gesagt, das grundlegende Problem, das eine Schnittstelle zu lösen versucht, besteht darin, zu trennen, wie wir etwas verwenden, und wie es implementiert wird. Sie sollten jedoch berücksichtigen, dass die Schnittstelle kein Vertrag ist . Lesen Sie hier mehr .