Это немного сложно, так как я не знаю ни одного формального определения S3 class
.Для объектов R классы S3 управляются очень простым символьным вектором имен классов, хранящимся в атрибуте class
.Диспетчеризация метода выполняется путем сопоставления элемента (ов) этого атрибута с именем функции.
По сути, вы можете сделать:
x <- 1:5
class(x) <- "MyMadeUpClass"
x
# [1] 1 2 3 4 5
# attr(,"class")
# [1] "MyMadeUpClass"
Действительно ли вышеприведенное определяет класс в интуитивном формальномпонимание термина?
Вы можете создать метод print
для объектов этого класса, например (входящий глупый пример):
print.MyMadeUpClass <- function(x, ...) {
print(sprintf("Pretty vector: %s", paste(x, collapse = ",")))
}
x
# [1] "Pretty vector: 1,2,3,4,5"
Важным отличием здесь является то, что методы в S3
- «принадлежат» (универсальные) функции, а не классы
- выбираются на основе классов аргументов, предоставляемых для вызова функции
Точка Iя пытаюсь сделать так, чтобы у S3 на самом деле не было формально определенного наследования (которое, как я полагаю, и есть то, что вы ищете), в отличие от S4
, который реализует это с помощью концепции contains
, поэтому я не совсем уверен, чтоВы хотели бы видеть в результате.
Очень хорошее чтение по теме «Объектно-ориентированное программирование, функциональное программирование и R» Джона М. Чемберса: https://arxiv.org/pdf/1409.3531.pdf
Редактировать (послередактирование вопроса) - пакет sloop :
С точки зрения S3, я думаю, что имеет смысл рассмотреть структуру обобщений и методов.Пакет sloop
очень полезен для этого: https://github.com/r-lib/sloop.