Методы и обновление полей
Часть раздела Объектно-ориентированное программирование путешествия по R на Coddy. Урок 38 из 57.
Методы помещаются в список methods функции setRefClass(). Внутри метода поля являются обычными именами, а <<- изменяет поле. В среде выполнения Coddy R выводит сообщение о необязательном пакете codetools, когда определяется класс с методами, поэтому заключите определение в suppressMessages():
Counter <- suppressMessages(setRefClass("Counter",
fields = list(count = "numeric"),
methods = list(
add = function(n = 1) {
count <<- count + n
},
report = function() paste("count is", count)
)
))
c1 <- Counter$new(count = 0)
c1$add()
c1$add(5)
print(c1$report())Вывод:
[1] "count is 6".self — это объект, для которого был вызван метод. Метод, завершающийся вызовом invisible(.self), возвращает объект, поэтому вызовы можно объединять в цепочку:
Counter <- suppressMessages(setRefClass("Counter",
fields = list(count = "numeric"),
methods = list(
add = function(n = 1) {
count <<- count + n
invisible(.self)
}
)
))
c1 <- Counter$new(count = 0)
c1$add(2)$add(3)$add(4)
print(c1$count)Результат:
[1] 9Метод initialize выполняется внутри $new(). initFields(...) задаёт переданные поля; после этого метод может задать значения по умолчанию для остальных. Методы вызывают друг друга по имени:
Account <- suppressMessages(setRefClass("Account",
fields = list(owner = "character", balance = "numeric"),
methods = list(
initialize = function(...) {
initFields(...)
if (length(balance) == 0) balance <<- 0
invisible(.self)
},
deposit = function(x) balance <<- balance + x,
deposit_twice = function(x) {
deposit(x)
deposit(x)
}
)
))
a <- Account$new(owner = "Ada")
a$deposit_twice(10)
print(a$balance)Результат:
[1] 20Внутри метода обычное <- для имени поля создаёт локальную переменную с этим именем и оставляет поле без изменений. Используйте <<- при каждом изменении поля:
Counter <- suppressMessages(setRefClass("Counter",
fields = list(count = "numeric"),
methods = list(
broken = function() count <- count + 1,
working = function() count <<- count + 1
)
))
c1 <- Counter$new(count = 0)
c1$broken()
c1$broken()
c1$working()
print(c1$count)Результат:
[1] 1Задание
ЛегкоЗавершите реализацию ссылочного класса Stack в Stack.R. Он хранит свои элементы в поле items (тип character, последний элемент находится сверху) и имеет четыре метода:
push(x)добавляетxнаверх и возвращаетinvisible(.self), поэтому вызовыpushможно объединять в цепочку;pop()удаляет и возвращает верхний элемент или возвращаетnothing, если стек пуст;peek()возвращает верхний элемент, не удаляя его, илиnothing;size()возвращает количество элементов.
Определение уже обёрнуто в suppressMessages(). Предоставленный код считывает команды push a b, pop и peek, затем добавляет ещё два элемента одним цепочечным вызовом и выводит размер.
Ваш код должен находиться в Stack.R. В main.R находится предоставленный код ввода/вывода, и его нельзя редактировать.
Попробуйте сами
source("Stack.R")
# Предоставленный код ввода/вывода: оставьте его как есть
input <- suppressWarnings(readLines(file("stdin")))
s <- Stack$new()
for (cmd in input) {
if (startsWith(cmd, "push ")) {
items <- strsplit(substring(cmd, 6), " ")[[1]]
for (it in items) s$push(it)
} else if (cmd == "pop") {
cat("popped ", s$pop(), "\n", sep = "")
} else if (cmd == "peek") {
cat("top ", s$peek(), "\n", sep = "")
}
}
s$push("x")$push("y")
cat("size after two chained pushes: ", s$size(), "\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