Ruby tem interfaces como qualquer outra linguagem.
Observe que você deve ter cuidado para não confundir o conceito de Interface , que é uma especificação abstrata das responsabilidades, garantias e protocolos de uma unidade com o conceito de interfaceque é uma palavra-chave na programação Java, C # e VB.NET línguas. Em Ruby, usamos o primeiro o tempo todo, mas o último simplesmente não existe.
É muito importante distinguir os dois. O que é importante é a interface , não o interface. O não interfacediz nada de útil. Nada demonstra isso melhor do que as interfaces de marcador em Java, que são interfaces que não possuem nenhum membro: basta dar uma olhada em java.io.Serializablee java.lang.Cloneable; esses dois interfacesignificam coisas muito diferentes, embora tenham exatamente a mesma assinatura.
Então, se dois interfaces que significam coisas diferentes têm a mesma assinatura, o que exatamente o interfacepar está garantindo a você?
Outro bom exemplo:
package java.util;
interface List<E> implements Collection<E>, Iterable<E> {
void add(int index, E element)
throws UnsupportedOperationException, ClassCastException,
NullPointerException, IllegalArgumentException,
IndexOutOfBoundsException;
}
Qual é a interface de java.util.List<E>.add?
- que o comprimento da coleção não diminua
- que todos os itens que estavam na coleção antes ainda estão lá
- que
elementestá na coleção
E qual desses realmente aparece no interface? Nenhum! Não há nada no interfaceque diz que o Addmétodo deve mesmo adicionar , ele também pode remover um elemento da coleção.
Esta é uma implementação perfeitamente válida de que interface:
class MyCollection<E> implements java.util.List<E> {
void add(int index, E element)
throws UnsupportedOperationException, ClassCastException,
NullPointerException, IllegalArgumentException,
IndexOutOfBoundsException {
remove(element);
}
}
Outro exemplo: onde java.util.Set<E>realmente diz que é, você sabe, um conjunto ? Lugar algum! Ou mais precisamente, na documentação. Em inglês.
Em praticamente todos os casos de interfaces, tanto do Java quanto do .NET, todas as informações relevantes estão na verdade nos documentos, não nos tipos. Portanto, se os tipos não dizem nada de interessante, por que mantê-los? Por que não ficar apenas com a documentação? E é exatamente isso que Ruby faz.
Observe que existem outras linguagens nas quais a Interface pode realmente ser descrita de uma forma significativa. No entanto, essas linguagens normalmente não chamam a construção que descreve a Interface " interface", eles a chamam type. Em uma linguagem de programação de tipo dependente, você pode, por exemplo, expressar as propriedades de que uma sortfunção retorna uma coleção do mesmo comprimento que o original, que cada elemento que está no original também está na coleção classificada e que nenhum elemento maior aparece antes de um elemento menor.
Resumindo: Ruby não tem equivalente a Java interface. Ele faz , no entanto, tem um equivalente a um Java interface , e é exatamente o mesmo que em Java: documentação.
Além disso, assim como em Java, os testes de aceitação também podem ser usados para especificar interfaces .
Em particular, em Ruby, a Interface de um objeto é determinada pelo que ele pode fazer , não o que classé ou o que moduleele se mistura. Qualquer objeto que tenha um <<método pode ser anexado. Isso é muito útil em testes de unidade, onde você pode simplesmente passar um Arrayou um em Stringvez de um mais complicado Logger, embora Arraye Loggernão compartilhe um explícito, interfaceexceto pelo fato de que ambos têm um método chamado <<.
Outro exemplo é StringIO, que implementa a mesma interface como IOe, portanto, uma grande porção da interface de File, mas sem qualquer partilha ancestral comum além Object.