Проверка с помощью inherits()
Часть раздела Объектно-ориентированное программирование путешествия по R на Coddy. Урок 15 из 57.
inherits(x, "employee") проверяет, присутствует ли employee где-либо в векторе классов x, поэтому для менеджеров также возвращает TRUE. Сравнение с class(x) == "employee" проверяет каждую позицию отдельно и возвращает вектор, что вызывает ошибку в if:
m <- structure(list(), class = c("manager", "employee"))
print(inherits(m, "employee"))
print(inherits(m, "intern"))
print(class(m) == "employee")Результат:
[1] TRUE
[1] FALSE
[1] FALSE TRUEЕсли указать несколько имён, inherits() возвращает TRUE, когда объект имеет хотя бы одно из них. С параметром which = TRUE функция возвращает для каждого имени его позицию в векторе классов или 0, если оно отсутствует:
p <- structure(list(), class = c("fragile", "express", "parcel"))
print(inherits(p, c("letter", "parcel")))
print(inherits(p, c("express", "letter", "parcel"), which = TRUE))Результат:
[1] TRUE
[1] 2 0 3Функция, которая имеет смысл только для одного семейства классов, проверяет свой аргумент с помощью inherits() и в противном случае останавливается с понятным сообщением:
raise <- function(x, pct) {
if (!inherits(x, "employee")) stop("raise() needs an employee", call. = FALSE)
x$salary <- x$salary * (1 + pct / 100)
x
}
m <- structure(list(salary = 50000), class = c("manager", "employee"))
print(raise(m, 10)$salary)
print(tryCatch(raise(list(salary = 1), 10), error = function(e) conditionMessage(e)))Результат:
[1] 55000
[1] "raise() needs an employee"Filter() с помощью inherits() выбирает элементы одного семейства из смешанного списка, включая все подклассы:
staff <- list(
structure(list(name = "Ada"), class = c("manager", "employee")),
structure(list(name = "Bo"), class = "employee"),
structure(list(name = "Cy"), class = c("intern", "employee")),
structure(list(name = "Dee"), class = c("director", "manager", "employee"))
)
managers <- Filter(function(x) inherits(x, "manager"), staff)
print(vapply(managers, function(x) x$name, character(1)))Результат:
[1] "Ada" "Dee"Задание
ЛегкоКаталог содержит книги, электронные книги и DVD. Конструкторы находятся в Item.R, Book.R, Ebook.R и Dvd.R; электронная книга имеет класс c("ebook", "book", "item"). В Catalogue.R реализуйте две функции с помощью inherits():
count_of(items, kind)возвращает количество элементов, у которыхkindвстречается где-либо в векторе классов.titles_of(items, kind)возвращает названия этих элементов в исходном порядке.
Предоставленный код считывает строки book Dune, ebook Emma, dvd Alien и обрабатывает запросы ? book, выводя book: 2 (Dune, Emma), или только dvd: 0, если совпадений нет.
Ваш код должен находиться в Item.R, Book.R, Ebook.R, Dvd.R и Catalogue.R. В main.R находится предоставленный код ввода/вывода, и его нельзя изменять.
Попробуйте сами
source("Item.R")
source("Book.R")
source("Ebook.R")
source("Dvd.R")
source("Catalogue.R")
# Предоставленный код ввода/вывода: оставьте его как есть
input <- suppressWarnings(readLines(file("stdin")))
items <- list()
for (line in input) {
p <- strsplit(line, " ")[[1]]
rest <- paste(p[-1], collapse = " ")
if (p[1] == "?") {
titles <- titles_of(items, p[2])
shown <- if (length(titles) > 0) paste0(" (", paste(titles, collapse = ", "), ")") else ""
cat(p[2], ": ", count_of(items, p[2]), shown, "\n", sep = "")
} else {
items[[length(items) + 1]] <- switch(p[1], book = new_book(rest), ebook = new_ebook(rest), dvd = new_dvd(rest))
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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