В Ruby, который является языком с динамической типизацией и допускает только одиночное наследование, вы можете имитировать «интерфейс» через миксины, а не загрязнять класс методами «интерфейса».
Миксины частично имитируют множественное наследование, что позволяет объекту «наследовать» от нескольких источников, но без двусмысленности и сложности фактического наличия нескольких родителей. Истинный родитель есть только один.
Для реализации интерфейса (в абстрактном смысле, а не фактического типа интерфейса, как в языках со статической типизацией) Вы определяете модуль, как если бы он был интерфейсом на статическом языке. Затем вы включаете его в класс. Вуаля! Вы собрали тип утки в то, что по сути является интерфейсом.
Очень упрощенный пример:
module Equippable
def weapon
"broadsword"
end
end
class Hero
include Equippable
def hero_method_1
end
def hero_method_2
end
end
class Mount
include Equippable
def mount_method_1
end
end
h = Hero.new
h.weapon # outputs "broadsword"
m = Mount.new
m.weapon # outputs "broadsword"
Equippable - это интерфейс для Hero, Mount и любого другого класса или модели, в который он входит.
(Очевидно, что оружие, скорее всего, будет динамически устанавливаться инициализатором, который был упрощен в этом примере.)