Функции доступа
Часть раздела Объектно-ориентированное программирование путешествия по R на Coddy. Урок 19 из 57.
Инкапсуляция означает, что другой код работает с объектом через функции, а не обращается напрямую к его полям. Геттер считывает значение, а сеттер изменяет его. Для списка S3 сеттер возвращает изменённую копию:
new_member <- function(name) structure(list(name = name), class = "member")
get_name <- function(p) p$name
set_name <- function(p, value) {
p$name <- value
p
}
p <- new_member("ada")
p <- set_name(p, "Ada Lovelace")
print(get_name(p))Результат:
[1] "Ada Lovelace"Аксессоры позволяют объекту изменять способ хранения данных, не нарушая код, который его использует. Этот термометр хранит температуру в градусах Цельсия, а геттер вычисляет градусы Фаренгейта по запросу, поэтому вызывающий код никогда не видит само поле:
new_thermo <- function(c) structure(list(c = c), class = "thermo")
celsius <- function(t) t$c
fahrenheit <- function(t) t$c * 9 / 5 + 32
t <- new_thermo(25)
cat(celsius(t), fahrenheit(t))Вывод:
25 77Собственные сеттеры R, такие как names(x) <- ..., являются функциями замены. Функция с именем "name<-" и параметрами x и value позволяет вызывающему коду записать name(p) <- "Bo"; R вызывает её и присваивает результат обратно p:
new_member <- function(name) structure(list(name = name), class = "member")
name <- function(p) p$name
"name<-" <- function(x, value) {
x$name <- trimws(value)
x
}
p <- new_member("ada")
name(p) <- " Bo "
print(name(p))Вывод:
[1] "Bo"Геттер объекта-замыкания возвращает копию приватных данных. Изменение этой копии не изменяет объект, поэтому попасть внутрь можно только через собственные функции объекта:
make_list <- function() {
items <- character(0)
list(add = function(x) items <<- c(items, x),
get_items = function() items)
}
todo <- make_list()
todo$add("milk")
mine <- todo$get_items()
mine[1] <- "HACKED"
print(todo$get_items())Вывод:
[1] "milk"Задание
ЛегкоКонтакт — это список S3 класса contact с полями name и email. Дополните Contact.R:
new_contact(name, email)сохраняет email после удаления пробелов и в нижнем регистре.- Геттеры
contact_name(x)иcontact_email(x). - Функция замены
"contact_email<-", которая сохраняет новый email после удаления пробелов и в нижнем регистре, чтобы вызывающий код мог использовать записьcontact_email(c1) <- value.
Предоставленный код считывает name,email, затем новые адреса email и после каждого изменения выводит Ada <ada@x.com>, а в конце — имена сохранённых полей.
Ваш код должен находиться в Contact.R. В main.R содержится предоставленный код ввода/вывода, и его нельзя редактировать.
Попробуйте сами
source("Contact.R")
# Предоставленный код ввода/вывода: оставьте его как есть
input <- suppressWarnings(readLines(file("stdin")))
p <- strsplit(input[1], ",")[[1]]
c1 <- new_contact(p[1], p[2])
cat(contact_name(c1), " <", contact_email(c1), ">\n", sep = "")
for (value in input[-1]) {
contact_email(c1) <- value
cat(contact_name(c1), " <", contact_email(c1), ">\n", sep = "")
}
cat("stored fields: ", paste(names(unclass(c1)), collapse = ", "), "\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