Ruby: рассуждения о наследовании

Конечно, классы в Ruby открыты для расширения. Но порядок интерпретации влияет на результат. Пример:

class A
end
 
class B < A
end
 
class B
   def m
   end
end

Так работает. Но если поменять местами два последних определения, то возникает сообщение об ошибке: superclass mismatch for class B (TypeError), поскольку указать базовый класс можно только при первоначальном определении класса.

Вообще, возможность добавления методов в существующий класс заставляет переосмыслить роль механизма наследования. На первый взгляд, в Ruby с открытыми определениями классов, динамической типизацией и duck typing наследование не требуется!

Программисты, «думающие» на C++/Java часто используют наследование не по назначению. Обсуждая с коллегой вопрос «зачем нужно наследование?» я наткнулся на быстрый ответ: для переиспользования кода. В этом и есть корень зла — при отсутствии нормальных механизмов повторного использования кода в этом качестве начинают использовать наследование. Но в Ruby-то такие механизмы есть. Так зачем наследование?

Похоже, что в Ruby и подобных языках наследование вернулось к своему первоначальному назначению — выразить намерение программиста, что один тип является подтипом другого. Кстати, если вспомнить принцип подстановки Лисков (Liskov substitution principle), то становится понятно, что подтип (subtype) тесно связан с подстановкой (substitution).

Вывод: используйте наследование в первую очередь как способ описания используемой модели, проектного решения. А уж потом реализуйте в классах требуемые методы.

07.04.2008  Метки:   Рубрики: Разработка, Языки

4 комментария

  1. allex - 07.04.2008

    Пара ссылок по теме из очень интересного блога:
    http://weblog.raganwald.com/2008/04/is-strictly-equivalent-to.html
    http://weblog.raganwald.com/2008/03/is-is-has.html

  2. Andrey - 29.06.2008

    Повторное использование кода было и остаётся главной целью наследования. Правило Лисков (и др. подобные) — это только правило определяющее когда наследование применимо.

  3. Andrey - 29.06.2008

    Повторное использование кода было и остаётся главной целью наследования. Принцип Лисков — это только правило, определяющее когда наследование применимо.

  4. allex - 30.06.2008

    Андрей, код можно использовать повторно и без наследования. Более того: наследование — это не лучший механизм для повторного использования кода…

Написать комментарий