Слоты и доступ
Часть раздела Объектно-ориентированное программирование путешествия по R на Coddy. Урок 23 из 57.
obj@slot <- value изменяет слот. Как и объекты S3, объекты S4 являются значениями: функция, изменяющая объект, работает с его собственной копией и возвращает её:
setClass("Person", slots = c(name = "character", age = "numeric"))
birthday <- function(p) {
p@age <- p@age + 1
p
}
ada <- new("Person", name = "Ada", age = 36)
older <- birthday(ada)
cat(ada@age, older@age)Вывод:
36 37slot(obj, "name") делает то же, что и @ с именем слота в строке, поэтому работает с именем, хранящимся в переменной. slotNames() перечисляет слоты класса или объекта:
setClass("Person", slots = c(name = "character", age = "numeric"))
ada <- new("Person", name = "Ada", age = 36)
for (s in slotNames(ada)) cat(s, "=", format(slot(ada, s)), "\n")
slot(ada, "age") <- 37
print(ada@age)Результат:
name = Ada
age = 36
[1] 37Каждое присваивание проверяется на соответствие объявленному типу, а не только new(). Неправильное значение отклоняется, и объект сохраняет старое значение:
setClass("Person", slots = c(name = "character", age = "numeric"))
ada <- new("Person", name = "Ada", age = 36)
ada@age <- "old"Результат:
Error in (function (cl, name, valueClass) :
assignment of an object of class “character” is not valid for @‘age’ in an object of class “Person”; is(value, "numeric") is not TRUE
Execution haltedgetSlots() возвращает имя каждого слота с его объявленным типом, что позволяет коду преобразовать текстовый ввод в тип, ожидаемый слотом:
setClass("Person", slots = c(name = "character", age = "numeric"))
types <- getSlots("Person")
print(types)
value <- "40"
if (types[["age"]] == "numeric") value <- as.numeric(value)
print(value + 1)Вывод:
name age
"character" "numeric"
[1] 41Задание
ЛегкоКласс Profile в Profile.R имеет слоты name и city (строковые), а также age (числовой). Завершите две функции:
update_profile(p, field, value)останавливается с сообщениемno field email(используйтеcall. = FALSE), если поле не является слотом; в противном случае преобразует текстовое значениеvalueс помощьюas.numeric(), если слот числовой, задаёт слот с помощьюslot()и возвращает изменённый профиль.profile_lines(p)возвращает по одной строке для каждого слота в порядке слотов:name: Ada.
Предоставленный код считывает имя, затем строки city=Paris или age=36, применяет каждую из них и выводит строки профиля.
Ваш код должен находиться в Profile.R. В main.R содержится предоставленный код ввода/вывода, и его нельзя редактировать.
Попробуйте сами
source("Profile.R")
# Предоставленный код ввода/вывода: оставьте его как есть
input <- suppressWarnings(readLines(file("stdin")))
p <- new("Profile", name = input[1], city = "unknown", age = 0)
for (line in input[-1]) {
kv <- strsplit(line, "=")[[1]]
p <- tryCatch(update_profile(p, kv[1], kv[2]), error = function(e) {
cat("error: ", conditionMessage(e), "\n", sep = "")
p
})
}
for (l in profile_lines(p)) cat(l, "\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