Ответ 1
Кажется, вы уже знаете некоторые определения и применения для разных типов ООП. Я дам свое мнение о том, когда это целесообразно использовать.
-
Используйте классы S3 для ситуаций, в которых применяются оба следующих условия: (a) ваш объект статичен, а не самомодифицируется, и (b) вам не нужны сигнатуры методов с несколькими аргументами, т.е. ваш метод отправляет чисто по первому аргументу, классу S3 объекта. Кроме того, классы S3 являются хорошим решением, когда вы можете жить с этими ограничениями и хотите перегрузить многие операторы.
-
Используйте классы S4, если ваш объект статичен, а не самомодифицирован, но вы заботитесь о сигнатурах с несколькими аргументами. По моему опыту, S4 OOP всегда был более сложным, чем того стоит, хотя он "гарантирует" тип безопасности в некоторой степени.
-
Используйте ссылочные классы, если ваш объект самомодифицируется. В противном случае вам придется определить многие методы замены (например,
some_method<-
, который вызывается с синтаксисомsome_method(obj) <- value
). Это неудобно и вычислительно медленно, так как R будет создавать полную копию объекта каждый раз. R6 - хорошая замена, хотя я не счел это необходимым для моих целей.
Большинство людей, новых для R, думают, что это смущает; что причиной столь многих реализаций ООП является отсутствие консенсуса.
Это неверно.
Из-за его статистического характера большинство гетерогенных структур в R (то есть вещей, которые должны быть объективными) в конечном итоге являются результатом статистического алгоритма: объект lm, glmnet, gbm и т.д. Обычно достаточно объединить эту информацию и предоставить ожидаемые интерфейсы для ее суммирования: print
, summary
и т.д.
Благодаря своему наследию как статистической игровой площадке это освобождает пользователя от необходимости думать о более продвинутых концепциях, таких как наследование и распределение/де-распределение, и открывает игровое поле для большего количества участников. Это означает, что в R немного сложнее создавать сложные сложные проекты (например, веб-серверы, текстовые синтаксические анализаторы, графические интерфейсы и т.д.), Чем в типичном объектно-ориентированном языке, таком как Ruby, но отсутствие единого OOP-типа сбалансированный простотой использования.
Последний способ подумать о том, что разные подходы похожи на фазовые переходы в веществе: твердом, газообразном, жидком. Вместо того, чтобы относиться ко всем гетерогенным структурам (т.е. К ООП-подобным вещам) равномерно, некоторые из них более естественны под одной структурой, чем другие. Если я обертываю простой список в классе S3, чтобы хорошо отображать перегруженный метод print
, было бы довольно глупо настраивать для этой цели целый ссылочный класс.