Es kann von Vorteil sein, an Schnittstellen zu programmieren, auch wenn wir nicht von Abstraktionen abhängig sind.
Programmierung an Schnittstellen zwingt uns dazu, eine kontextabhängige Teilmenge eines Objekts zu verwenden . Das hilft, weil es:
- verhindert, dass wir kontextuell unangemessene Dinge tun, und
- können wir die Implementierung in der Zukunft sicher ändern.
Nehmen wir zum Beispiel eine Person
Klasse, die die Friend
und die Employee
Schnittstelle.
class Person implements AbstractEmployee, AbstractFriend {
}
Im Zusammenhang mit dem Geburtstag der Person programmieren wir zum Friend
Schnittstelle, um zu verhindern, dass die Person wie ein Employee
.
function party() {
const friend: Friend = new Person("Kathryn");
friend.HaveFun();
}
Im Zusammenhang mit der Arbeit der Person, programmieren wir auf die Employee
Schnittstelle, um zu verhindern, dass die Grenzen am Arbeitsplatz verschwimmen.
function workplace() {
const employee: Employee = new Person("Kathryn");
employee.DoWork();
}
Großartig. Wir haben uns in verschiedenen Kontexten angemessen verhalten, und unsere Software funktioniert gut.
In ferner Zukunft, wenn sich unser Geschäft auf die Arbeit mit Hunden umstellt, können wir die Software relativ einfach ändern. Zunächst erstellen wir eine Dog
Klasse, die beides implementiert Friend
y Employee
. Dann ändern wir sicher new Person()
à new Dog()
. Selbst wenn beide Funktionen Tausende von Codezeilen haben, wird diese einfache Bearbeitung funktionieren, weil wir wissen, dass die folgenden Punkte zutreffen:
- Funktion
party
verwendet nur die Friend
Teilmenge von Person
.
- Funktion
workplace
verwendet nur die Employee
Teilmenge von Person
.
- Klasse
Dog
implementiert sowohl die Friend
y Employee
Schnittstellen.
Andererseits, wenn entweder party
ou workplace
programmiert haben sollten gegen Person
würde das Risiko bestehen, dass beide Person
-spezifischen Code. Der Wechsel von Person
à Dog
müssten wir den Code durchkämmen, um alle Person
-spezifischer Code, der Dog
nicht unterstützt.
Die Moral Programmierung für Schnittstellen: Die Programmierung für Schnittstellen hilft unserem Code, sich angemessen zu verhalten und auf Veränderungen vorbereitet zu sein. Außerdem bereitet es unseren Code auf die Abhängigkeit von Abstraktionen vor, was noch mehr Vorteile bringt.
4 Stimmen
Wenn Sie sich daran erinnern können und Ihr Programm optimal sein soll, können Sie kurz vor der Kompilierung die Schnittstellendeklaration gegen die tatsächliche Implementierung austauschen. Die Verwendung einer Schnittstelle fügt eine Ebene der Indirektion hinzu, die zu Leistungseinbußen führt. Verteilen Sie Ihren auf Schnittstellen programmierten Code jedoch...
25 Stimmen
@Ande Turner: Das ist ein schlechter Ratschlag. 1). "Ihr Programm muss optimal sein" ist kein guter Grund für das Auslagern von Schnittstellen! Dann sagen Sie: "Verteilen Sie Ihren programmierten Code trotzdem auf Schnittstellen..." Sie raten also, dass Sie bei Anforderung (1) dann suboptimalen Code veröffentlichen?!?
82 Stimmen
Die meisten der Antworten hier sind nicht ganz richtig. Es bedeutet nicht oder impliziert nicht einmal "das Schlüsselwort interface verwenden". Eine Schnittstelle ist eine Spezifikation, wie etwas zu verwenden ist - gleichbedeutend mit dem Vertrag (schlagen Sie es nach). Getrennt davon ist die Implementierung, die besagt, wie der Vertrag erfüllt wird. Programmieren Sie nur gegen die Garantien der Methode/des Typs, so dass, wenn die Methode/der Typ auf eine Weise geändert wird, die immer noch dem Vertrag entspricht, der Code, der sie verwendet, nicht kaputt geht.
2 Stimmen
@apollodude217 das ist eigentlich die beste Antwort auf der ganzen Seite. Zumindest für die Frage im Titel, da es hier mindestens 3 ganz unterschiedliche Fragen gibt...
7 Stimmen
Das grundsätzliche Problem bei Fragen wie dieser ist, dass sie davon ausgehen, dass "Programmieren für eine Schnittstelle" bedeutet, "alles in eine abstrakte Schnittstelle verpacken", was albern ist, wenn man bedenkt, dass der Begriff das Konzept der abstrakten Schnittstellen im Java-Stil vorwegnimmt.
0 Stimmen
Dies geschieht meist mit COM. Man behandelt ein Objekt, ohne die Klasse zu kennen, sondern nur die Schnittstelle, die es unterstützt.
0 Stimmen
Es ist nur ein schickes Wort für Rückruf . Das ist alles, was es bedeutet. Es bedeutet nur, dass Sie etwas tun (z. B. "Informationen aus dem Netz holen" oder "eine Berechnung durchführen"). Diese andere Sache wird schließlich eine Funktion aufrufen von Ihnen, um Ihnen das Ergebnis mitzuteilen. Oder? Sie müssen also irgendwie den Namen dieser Funktion angeben (die Rückruffunktion). Die "Schnittstelle!" gibt nur den Namen dieser Funktion an. Das ist alles, mehr gibt es nicht.
2 Stimmen
Der Klassiker
List lst = new ArrayList();
bedeutet nur, dass Sie einschränken, welche Funktionen des erstellten Objekts Ihnen zur Verfügung stehen, was völlig dumm ist. Dieses seltsame Konstrukt wird von Java-Lehrern und -Büchern ohne ersichtlichen Grund immer wieder propagiert.0 Stimmen
@Damien, Sie sollten diese Frage nicht mit weiteren Fragen verwechseln. SO ist eine Seite mit 1 Frage pro Thema. Es ist besser, separate Fragen zu stellen und auf diese Frage zu verweisen, wenn sie relevant ist.
1 Stimmen
@Nyerguds Heiliger Bimbam, ganz und gar nicht! Ein Stück Code sollte den engstmöglichen Typ verwenden, da es sich um selbstdokumentierenden Code handelt. Durch diese Einschränkung des Typs weiß ein Programmierer automatisch mehr darüber, wie er verwendet werden könnte. Nehmen wir einen Code, der Folgendes verwendet
ArrayList
. Es könnte tatsächlich etwas Spezielles für diese Implementierung in der Verwendung von ihr erfordern. Dann denken Sie daran, dass SieIterable
- Sie wissen jetzt zu 100 %, dass der Code nur in einer for each-Schleife verwendet wird. Auf diese Weise wird viel mehr Information in einem verständlichen Code vermittelt.0 Stimmen
@user904963 Das bedeutet auch, dass Ihre Funktion eingeschränkt nur für eine Schleife zu verwenden. Das könnte Ihnen bei späteren Aktualisierungen in den Hintern beißen, wenn Sie drei Funktionen tiefer in das Projekt einsteigen.
0 Stimmen
@Nyerguds Ein ähnliches Problem kann auftreten, wenn Sie einen unnötig spezifischen Typ anfordern. Sie können die Implementierung niemals durch einen verwandten Typ ersetzen, der anders implementiert ist. Es ist ein unzulässiger Kurzschluss in der Logik, Allgemeinheit in einem Code als "völlig dumm" zu bezeichnen. Jede Art von Allgemeinheit/Spezifität hat ihren Zweck, aber im Allgemeinen bietet Ihnen die Verwendung des am wenigsten spezifischen Typs die meisten Möglichkeiten, den Code zu ändern. Fragen Sie nach einer
ArrayList
ist beispielsweise nur dann sinnvoll, wenn ein Teil Ihrer API eine Geschwindigkeitsgarantie ist, die auf zusammenhängenden Speicher angewiesen ist. Der meiste Code wird nur eineList
.0 Stimmen
@user904963 Ist nicht ArrayList buchstäblich die einzige Implementierung von List auf Java sowieso?
0 Stimmen
@Nyerguds Nur für die Standardimplementierungen, die in Java eingebaut sind, schauen Sie sich hier "implementiert von" an: docs.oracle.com/javase/8/docs/api/java/util/List.html . Es gibt
AbstractList
,AbstractSequentialList
,ArrayList
,AttributeList
,CopyOnWriteArrayList
,LinkedList
,RoleList
,RoleUnresolvedList
,Stack
etVector
. Sie können auch benutzerdefinierte Klassen erstellen, die dieList
Schnittstelle oder verwenden Sie den Code anderer Personen, die sie implementieren.