Ruby ha interfacce proprio come qualsiasi altra lingua.
Si noti che bisogna stare attenti a non confondere il concetto di Interfaccia , che è una specifica astratta delle responsabilità, garanzie e protocolli di un'unità con il concetto di interface
quale è una parola chiave nella programmazione Java, C # e VB.NET le lingue. In Ruby, usiamo sempre il primo, ma il secondo semplicemente non esiste.
È molto importante distinguere i due. Ciò che è importante è l' interfaccia , non il file interface
. Non interface
ti dice praticamente nulla di utile. Niente lo dimostra meglio delle interfacce marker in Java, che sono interfacce che non hanno alcun membro: basta dare un'occhiata a java.io.Serializable
e java.lang.Cloneable
; quei due interface
significano cose molto diverse, ma hanno la stessa identica firma.
Quindi, se due interface
s che le cose medi diverse, hanno la stessa firma, che cosa esattamente è il interface
anche garantendo te?
Un altro buon esempio:
package java.util;
interface List<E> implements Collection<E>, Iterable<E> {
void add(int index, E element)
throws UnsupportedOperationException, ClassCastException,
NullPointerException, IllegalArgumentException,
IndexOutOfBoundsException;
}
Qual è l' interfaccia di java.util.List<E>.add
?
- che la lunghezza della raccolta non diminuisca
- che tutti gli elementi che erano nella collezione prima sono ancora lì
- che
element
è nella raccolta
E quale di questi si presenta effettivamente nel interface
? Nessuna! Non c'è niente in interface
ciò che dice che il Add
metodo deve anche aggiungere del tutto, potrebbe anche rimuovere un elemento dalla raccolta.
Questa è un'implementazione perfettamente valida di ciò interface
:
class MyCollection<E> implements java.util.List<E> {
void add(int index, E element)
throws UnsupportedOperationException, ClassCastException,
NullPointerException, IllegalArgumentException,
IndexOutOfBoundsException {
remove(element);
}
}
Un altro esempio: dove java.util.Set<E>
si dice effettivamente che è, sai, un set ? Da nessuna parte! O più precisamente, nella documentazione. In inglese.
In quasi tutti i casi interfaces
, sia da Java che da .NET, tutte le informazioni rilevanti sono effettivamente nei documenti, non nei tipi. Quindi, se i tipi non ti dicono comunque nulla di interessante, perché tenerli affatto? Perché non limitarti alla documentazione? Ed è esattamente quello che fa Ruby.
Si noti che esistono altre lingue in cui l' interfaccia può essere effettivamente descritta in modo significativo. Tuttavia, questi linguaggi in genere non chiamano il costrutto che descrive l' interfaccia " interface
", lo chiamano type
. In un linguaggio di programmazione tipizzato in modo dipendente, puoi, ad esempio, esprimere le proprietà che una sort
funzione restituisce una raccolta della stessa lunghezza dell'originale, che ogni elemento che è nell'originale è anche nella raccolta ordinata e che nessun elemento più grande appare prima di un elemento più piccolo.
Quindi, in breve: Ruby non ha un equivalente a Java interface
. Essa ha , tuttavia, hanno un equivalente ad un Java Interface , ed è esattamente lo stesso come in Java: la documentazione.
Inoltre, proprio come in Java, i test di accettazione possono essere utilizzati anche per specificare le interfacce .
In particolare, in Ruby, l' interfaccia di un oggetto è determinata da ciò che può fare , non da ciò che class
è o da cosa module
si mescola. Qualsiasi oggetto che abbia un <<
metodo può essere aggiunto. Questo è molto utile negli unit test, dove puoi semplicemente passare un Array
o a String
invece di un più complicato Logger
, anche se Array
e Logger
non condividere un esplicito a interface
parte il fatto che entrambi hanno un metodo chiamato <<
.
Un altro esempio è StringIO
, che implementa la stessa interfaccia come IO
e quindi una grande porzione della interfaccia di File
, ma senza condividere alcun antenato comune oltre Object
.