У Ruby є інтерфейси, як і будь-яка інша мова.
Зауважте, що ви повинні бути обережними, щоб не співставити поняття Інтерфейс , який є абстрактною специфікацією обов'язків, гарантій та протоколів підрозділу з поняттям, interfaceяке є ключовим словом у програмах Java, C # та VB.NET мови. У Рубі ми постійно використовуємо перше, але останнє просто не існує.
Дуже важливо розрізняти два. Важливим є інтерфейс , а не інтерфейсinterface . У interfaceвас майже нічого корисного немає. Ніщо не демонструє це краще , ніж інтерфейси маркерів в Java, які є інтерфейси , які не мають членів на всіх: просто подивіться на java.io.Serializableі java.lang.Cloneable; ці два interfaceзначать дуже різні речі, але вони мають точно такий же підпис.
Отже, якщо два interfaces, що означають різні речі, мають один і той же підпис, що саме це вам interfaceнавіть гарантує?
Ще один хороший приклад:
package java.util;
interface List<E> implements Collection<E>, Iterable<E> {
void add(int index, E element)
throws UnsupportedOperationException, ClassCastException,
NullPointerException, IllegalArgumentException,
IndexOutOfBoundsException;
}
Що таке інтерфейс з java.util.List<E>.add?
- що довжина колекції не зменшується
- що всі предмети, які були в колекції раніше, все ще є
- що
elementє в колекції
І хто з них насправді з'являється у interface? Жоден! У цьому немає нічого, interfaceщо говорить про те, що Addметод повинен взагалі додаватись , він може так само добре видалити елемент із колекції.
Це цілком коректна реалізація цього interface:
class MyCollection<E> implements java.util.List<E> {
void add(int index, E element)
throws UnsupportedOperationException, ClassCastException,
NullPointerException, IllegalArgumentException,
IndexOutOfBoundsException {
remove(element);
}
}
Інший приклад: де в java.util.Set<E>насправді йдеться про те, що це, знаєте, набір ? Нікуди! Або точніше, в документації. Англійською.
В основному у всіх випадках interfaces, як з Java, так і з .NET, вся відповідна інформація є фактично в документах, а не в типах. Тож, якщо типи все одно не розповідають тобі нічого цікавого, навіщо їх взагалі тримати? Чому б не дотримуватися лише документації? І саме цим займається Рубі.
Зауважте, що існують й інші мови, якими інтерфейс можна насправді описати змістовно. Однак ці мови, як правило, не називають конструкцію, яка описує " " інтерфейс, а " interface" type. Наприклад, у мові програмування залежно від типу ви можете висловити властивості, що sortфункція повертає колекцію тієї самої довжини, що й оригінал, що кожен елемент, що знаходиться в оригіналі, також знаходиться в відсортованій колекції і що немає більшого елемента з'являється перед меншим елементом.
Отже, коротше: у Ruby немає еквівалента Java interface. Він робить , однак, має еквівалент Java - інтерфейс , і це точно так же , як і в Java: документація.
Крім того, як і в Java, тести прийняття можуть використовуватися і для визначення інтерфейсів .
Зокрема, в Ruby інтерфейс об'єкта визначається тим, що він може робити , а не що classє, або що moduleвін змішує. До будь-якого об'єкта, який має <<метод, можна додати. Це дуже корисно в одиничних тестах, де ви можете просто Передавайте Arrayабо Stringзамість більш складних Logger, хоча Arrayі Loggerне поділяєте явні interfaceкрім того , що вони обидва мають метод , званий <<.
Інший приклад може служити StringIO, який реалізує той же інтерфейс , як IOі , отже , більша частина інтерфейсу з File, але без якого - або спільного загального предка , крім Object.