Порядок поиска методов
Часть раздела Объектно-ориентированное программирование путешествия по R на Coddy. Урок 13 из 57.
При каждом вызове R просматривает вектор классов слева направо и запускает первый найденный метод. Если ни у одного класса нет метода, используется метод по умолчанию. Разные объекты в одной иерархии могут останавливаться на разных уровнях:
move <- function(x) UseMethod("move")
move.animal <- function(x) "walks"
move.bird <- function(x) "flies"
move.default <- function(x) "stays"
penguin <- structure(list(), class = c("penguin", "bird", "animal"))
dog <- structure(list(), class = c("dog", "animal"))
rock <- structure(list(), class = "rock")
cat(move(penguin), move(dog), move(rock))Вывод:
flies walks staysДочерний класс переопределяет метод родительского класса, определяя собственный метод. Переопределение влияет только на дочерний класс и всё, что находится ниже него; родительский класс и его другие дочерние классы сохраняют метод родительского класса:
move <- function(x) UseMethod("move")
move.animal <- function(x) "walks"
move.bird <- function(x) "flies"
move.penguin <- function(x) "swims"
penguin <- structure(list(), class = c("penguin", "bird", "animal"))
sparrow <- structure(list(), class = c("bird", "animal"))
cat(move(penguin), move(sparrow))Результат:
swims fliesКаждый generic ищется независимо. Один объект может получить sound() из собственного класса и move() от родительского класса, а метод родительского класса может снова вызвать другие generic-функции, которые выполняют диспетчеризацию по дочернему классу:
sound <- function(x) UseMethod("sound")
move <- function(x) UseMethod("move")
describe <- function(x) UseMethod("describe")
sound.animal <- function(x) "..."
sound.dog <- function(x) "woof"
move.animal <- function(x) "walks"
describe.animal <- function(x) paste(x$name, "says", sound(x), "and", move(x))
rex <- structure(list(name = "Rex"), class = c("dog", "animal"))
print(describe(rex))Результат:
[1] "Rex says woof and walks"Для объекта с атрибутом класса диспетчеризация смотрит только на этот атрибут, а затем — на значение по умолчанию. Сам объект внутри по-прежнему является списком, но метод для list не проверяется:
size <- function(x) UseMethod("size")
size.list <- function(x) "a list"
size.default <- function(x) "default"
bag <- structure(list(1, 2), class = "bag")
cat(size(list(1, 2)), "/", size(bag))Результат:
a list / defaultЗадание
ЛегкоКвадрат — это прямоугольник с равными сторонами. В Rectangle.R напишите методы area.rectangle(), perimeter.rectangle() и name.rectangle(), который возвращает rectangle 2x3. В Square.R завершите new_square(side), который вызывает new_rectangle() с классом square, и переопределите только name() с помощью name.square(), который возвращает square 2. Квадраты должны использовать area() и perimeter() прямоугольника.
Обобщения и new_rectangle() предоставлены. Предоставленный код считывает строки с двумя числами (прямоугольник) или одним числом (квадрат) и выводит square 2: area 4, perimeter 8.
Ваш код должен находиться в Rectangle.R и Square.R. В main.R содержится предоставленный код ввода/вывода, и его нельзя изменять.
Попробуйте сами
source("Rectangle.R")
source("Square.R")
# Предоставленный код ввода/вывода: оставьте его как есть
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
n <- as.numeric(strsplit(line, " ")[[1]])
s <- if (length(n) == 1) new_square(n[1]) else new_rectangle(n[1], n[2])
cat(name(s), ": area ", area(s), ", perimeter ", 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()Повторение — расчёт зарплаты сотрудниковПотренируйтесь самостоятельно: Онлайн-компилятор R