Ruby hat Schnittstellen wie jede andere Sprache.
Beachten Sie, dass Sie darauf achten müssen, das Konzept der Schnittstelle , bei der es sich um eine abstrakte Spezifikation der Verantwortlichkeiten, Garantien und Protokolle einer Einheit handelt, nicht mit dem Konzept des interface
Schlüsselworts in der Java-, C # - und VB.NET-Programmierung zu verknüpfen Sprachen. In Ruby verwenden wir das erstere ständig, aber das letztere existiert einfach nicht.
Es ist sehr wichtig, die beiden zu unterscheiden. Wichtig ist das Interface , nicht das interface
. Das interface
sagt dir so ziemlich nichts Nützliches. Nichts zeigt dies besser als die Marker-Schnittstellen in Java, bei denen es sich um Schnittstellen handelt, die überhaupt keine Mitglieder haben: Schauen Sie sich einfach java.io.Serializable
und an java.lang.Cloneable
. Diese beiden interface
bedeuten sehr unterschiedliche Dinge, haben aber genau die gleiche Signatur.
Also, wenn zwei interface
s , dass verschiedene Dinge bedeuten, die gleiche Signatur haben, was genau das ist interface
auch Sie garantiert?
Ein weiteres gutes Beispiel:
package java.util;
interface List<E> implements Collection<E>, Iterable<E> {
void add(int index, E element)
throws UnsupportedOperationException, ClassCastException,
NullPointerException, IllegalArgumentException,
IndexOutOfBoundsException;
}
Was ist die Schnittstelle von java.util.List<E>.add
?
- dass die Länge der Sammlung nicht abnimmt
- dass alle Gegenstände, die zuvor in der Sammlung waren, noch da sind
- das
element
ist in der Sammlung
Und welche davon taucht tatsächlich in der auf interface
? Keiner! Es gibt nichts in dem interface
, was besagt, dass die Add
Methode überhaupt etwas hinzufügen muss , sie könnte genauso gut ein Element aus der Sammlung entfernen .
Dies ist eine absolut gültige Implementierung davon interface
:
class MyCollection<E> implements java.util.List<E> {
void add(int index, E element)
throws UnsupportedOperationException, ClassCastException,
NullPointerException, IllegalArgumentException,
IndexOutOfBoundsException {
remove(element);
}
}
Ein weiteres Beispiel: Wo java.util.Set<E>
steht eigentlich, dass es sich um eine Menge handelt ? Nirgends! Oder genauer gesagt in der Dokumentation. Auf Englisch.
In so ziemlich allen Fällen interfaces
von Java und .NET befinden sich alle relevanten Informationen tatsächlich in den Dokumenten, nicht in den Typen. Also, wenn die Typen Ihnen sowieso nichts Interessantes sagen, warum sollten Sie sie überhaupt behalten? Warum nicht einfach bei der Dokumentation bleiben? Und genau das macht Ruby.
Beachten Sie, dass es andere Sprachen gibt, in denen die Schnittstelle tatsächlich auf sinnvolle Weise beschrieben werden kann. Diese Sprachen rufen jedoch normalerweise nicht das Konstrukt auf, das die Schnittstelle " interface
" beschreibt, sondern sie nennen es type
. In einer abhängig typisierten Programmiersprache können Sie beispielsweise die Eigenschaften ausdrücken, dass eine sort
Funktion eine Sammlung mit der gleichen Länge wie das Original zurückgibt, dass jedes Element im Original auch in der sortierten Sammlung enthalten ist und dass kein größeres Element vorhanden ist erscheint vor einem kleineren Element.
Kurz gesagt: Ruby hat kein Äquivalent zu Java interface
. Es entspricht jedoch einer Java- Schnittstelle und ist genau das gleiche wie in der Java: -Dokumentation.
Ebenso wie in Java können Akzeptanztests auch zum Angeben von Schnittstellen verwendet werden.
Insbesondere in Ruby, die Schnittstelle ist eines Objekts bestimmt durch das, was er kann tun , nicht das, was class
ist, oder was module
sie mischt in. Jedes Objekt , das eine hat <<
Methode kann angehängt werden. Dies ist sehr nützlich bei Unit-Tests, bei denen Sie einfach ein Array
oder ein String
statt eines komplizierteren bestehen könnenLogger
, obwohl Array
und Logger
teilen nicht eine explizite interface
abgesehen von der Tatsache , dass sie beide haben eine Methode aufgerufen <<
.
Ein anderes Beispiel ist StringIO
, dass dieselbe Schnittstelle wie IO
und damit ein großer Teil der Schnittstelle von implementiert File
wird, ohne jedoch einen gemeinsamen Vorfahren zu teilen Object
.