У Ruby є інтерфейси, як і будь-яка інша мова.
Зауважте, що ви повинні бути обережними, щоб не співставити поняття Інтерфейс , який є абстрактною специфікацією обов'язків, гарантій та протоколів підрозділу з поняттям, interface
яке є ключовим словом у програмах Java, C # та VB.NET мови. У Рубі ми постійно використовуємо перше, але останнє просто не існує.
Дуже важливо розрізняти два. Важливим є інтерфейс , а не інтерфейсinterface
. У interface
вас майже нічого корисного немає. Ніщо не демонструє це краще , ніж інтерфейси маркерів в Java, які є інтерфейси , які не мають членів на всіх: просто подивіться на java.io.Serializable
і java.lang.Cloneable
; ці два interface
значать дуже різні речі, але вони мають точно такий же підпис.
Отже, якщо два interface
s, що означають різні речі, мають один і той же підпис, що саме це вам 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
.