Создание обобщений
Часть раздела Объектно-ориентированное программирование путешествия по R на Coddy. Урок 27 из 57.
Дженерик S4 создаётся с помощью setGeneric(). Его тело функции — standardGeneric("name"), аналог UseMethod() в S4. setGeneric() возвращает имя дженерика, которое выводится при вызове на верхнем уровне:
setGeneric("area", function(shape) standardGeneric("area"))Вывод:
[1] "area"Оберни вызов в invisible(), чтобы эта строка не попала в вывод. setMethod("area", "Circle", ...) затем добавляет метод для одного класса:
setClass("Circle", slots = c(r = "numeric"))
setClass("Square", slots = c(side = "numeric"))
invisible(setGeneric("area", function(shape) standardGeneric("area")))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
setMethod("area", "Square", function(shape) shape@side^2)
cat(area(new("Circle", r = 1)), area(new("Square", side = 3)))Вывод:
3.141593 9Метод имеет те же аргументы, что и его обобщённая функция. Если у обобщённой функции есть ..., метод может добавить собственные именованные аргументы после них:
setClass("Circle", slots = c(r = "numeric"))
invisible(setGeneric("describe", function(x, ...) standardGeneric("describe")))
setMethod("describe", "Circle", function(x, ..., digits = 2) {
paste("circle of area", round(pi * x@r^2, digits))
})
c1 <- new("Circle", r = 2)
print(describe(c1))
print(describe(c1, digits = 4))Вывод:
[1] "circle of area 12.57"
[1] "circle of area 12.5664"Для работы setMethod() обобщённая функция должна уже существовать, поэтому сначала загружается файл с setGeneric(). Вызов для класса без метода завершается ошибкой, в которой указана сигнатура:
invisible(setGeneric("area", function(shape) standardGeneric("area")))
setClass("Circle", slots = c(r = "numeric"))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
area(42)Вывод:
Error: unable to find an inherited method for function ‘area’ for signature ‘shape = "numeric"’
Execution haltedЗадание
ЛегкоФигуры — это классы S4 в трёх файлах. В Shape.R создайте обобщённые функции area(shape) и perimeter(shape) с помощью setGeneric(), обернув их в invisible(). В Circle.R и Square.R объявляются классы; добавьте для каждого методы area и perimeter с помощью setMethod().
Предоставленный код читает строки circle 2 или square 3 и выводит circle: area 12.57, perimeter 12.57.
Ваш код нужно разместить в Shape.R, Circle.R и Square.R. В main.R находится предоставленный код ввода/вывода, и его нельзя редактировать.
Попробуйте сами
source("Shape.R")
source("Circle.R")
source("Square.R")
# Предоставленный код ввода-вывода: оставьте его без изменений
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, " ")[[1]]
s <- if (p[1] == "circle") new("Circle", r = as.numeric(p[2])) else new("Square", side = as.numeric(p[2]))
cat(sprintf("%s: area %.2f, perimeter %.2f", p[1], area(s), perimeter(s)), "\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()Повторение — расчёт зарплаты сотрудников6S4: обобщения и методы
Создание обобщенийМетоды для встроенных объектовДиспетчеризация по двум аргументамsetValidity и validObjectПовторение — деньги и валютаПотренируйтесь самостоятельно: Онлайн-компилятор R