Списки с классом
Часть раздела Объектно-ориентированное программирование путешествия по R на Coddy. Урок 2 из 57.
S3 — старейшая и наиболее часто используемая объектная система R. Объект S3 — это обычный список с атрибутом class, меткой, указывающей, к какому типу объектов он относится. class(x) <- "dog" задаёт эту метку:
rex <- list(name = "Rex", age = 3)
class(rex) <- "dog"
print(class(rex))
cat(rex$name, "is", rex$age)Вывод:
[1] "dog"
Rex is 3structure() создаёт значение и задаёт его атрибуты одним вызовом — это обычный способ создать объект S3. Поля считываются с помощью $, как в любом списке:
rex <- structure(list(name = "Rex", age = 3), class = "dog")
print(class(rex))
print(is.list(rex))
print(rex$age)Результат:
[1] "dog"
[1] TRUE
[1] 3Класс — это всего лишь метка: R не проверяет, какие поля есть у объекта, поэтому любой список можно назвать dog. unclass() удаляет метку и возвращает обычный список:
p <- structure(list(x = 1, y = 2), class = "point")
print(unclass(p))Вывод:
$x
[1] 1
$y
[1] 2Объекты S3 являются значениями. Функция, изменяющая объект, изменяет свою собственную копию, поэтому она возвращает новую версию, а вызывающая сторона присваивает её. Исходный объект остаётся прежним:
birthday <- function(d) {
d$age <- d$age + 1
d
}
rex <- structure(list(name = "Rex", age = 3), class = "dog")
older <- birthday(rex)
cat(rex$age, older$age)Вывод:
3 4Задание
ЛегкоЗавершите make_pet(name, species, age) в Pet.R. Она возвращает список с полями name, species и age в этом порядке и классом pet. Затем завершите describe_pet(p), которая возвращает одно предложение: для питомца по имени Rex, вида dog и возраста 3 результатом будет Rex is a 3 year old dog.
Предоставленный код считывает имя, вид и возраст, создаёт питомца и выводит его класс, имена его полей и предложение.
Ваш код должен находиться в Pet.R. В main.R содержится предоставленный код ввода/вывода, и его нельзя редактировать.
Попробуйте сами
source("Pet.R")
# Предоставленный код ввода/вывода: оставьте его как есть
input <- suppressWarnings(readLines(file("stdin")))
p <- make_pet(input[1], input[2], as.numeric(input[3]))
cat("class: ", class(p), "\n", sep = "")
cat("fields: ", paste(names(p), collapse = ", "), "\n", sep = "")
cat(describe_pet(p), "\n", sep = "")
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы S3
Работа с файламиСписки с классомФункции-конструкторыМетоды print и formatВалидаторы и вспомогательные функцииПовторение — температуры4Инкапсуляция в R
Замыкания как объектыОкружения как объектыФункции доступаЗащита состоянияПовторение — парковочный счётчик7S4 Наследование
Расширение с помощью containscallNextMethodВиртуальные классыПроверка типов с помощью is()Повторение — смотритель зоопарка10Шаблоны проектирования, часть 2
Шаблон «Декоратор»Шаблон «Строитель»Шаблон «Состояние»Шаблон «Итератор»2Обобщённые функции и методы S3
Обобщённые функции и UseMethodМетоды по умолчаниюМетоды для базовых обобщённых функцийОсновы NextMethodПовторение — площади фигур5Классы S4
Определение классов S4Слоты и доступПроверка корректностиМетоды showПовторение — каталог товаров8Ссылочные классы
Определение ссылочных классовМетоды и обновление полейСемантика копированияНаследование и callSuperПовторение — очередь задач11Проект: Управление библиотекой
Книги и читателиВыдача книг3Наследование S3
Векторы классовПорядок поиска методовРасширение с помощью NextMethodПроверка с помощью inherits()Повторение — расчёт зарплаты сотрудниковПотренируйтесь самостоятельно: Онлайн-компилятор R