Menu
Coddy logo textTech

Orden de búsqueda de métodos

Parte de la sección Programación orientada a objetos del Journey de R de Coddy. Lección 13 de 57.

En cada llamada, R recorre el vector de clases de izquierda a derecha y ejecuta el primer método que encuentra. Si ninguna clase tiene un método, utiliza el predeterminado. Distintos objetos de una misma jerarquía pueden detenerse en diferentes niveles:

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))

Salida:

flies walks stays

Una clase hija anula un método de la clase padre al definir el suyo propio. La anulación solo afecta a la clase hija y a todo lo que esté por debajo de ella; la clase padre y sus otras clases hijas conservan el método de la clase padre:

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))

Salida:

swims flies

Cada función genérica se busca por separado. Un objeto puede tomar sound() de su propia clase y move() de una clase principal, y un método de la clase principal puede llamar a otras funciones genéricas que vuelven a seleccionar el método según la clase secundaria:

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))

Salida:

[1] "Rex says woof and walks"

Para un objeto con un atributo de clase, el despacho solo se fija en ese atributo y después en el valor predeterminado. El objeto sigue siendo internamente una lista, pero no se prueba un método para 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))

Salida:

a list / default
challenge icon

Desafío

Fácil

Un cuadrado es un rectángulo con lados iguales. En Rectangle.R, escribe los métodos area.rectangle(), perimeter.rectangle() y name.rectangle(), que devuelve rectangle 2x3. En Square.R, completa new_square(side), que llama a new_rectangle() con la clase square, y sobrescribe solo name() con name.square(), que devuelve square 2. Los cuadrados deben usar los métodos area() y perimeter() del rectángulo.

Los genéricos y new_rectangle() se proporcionan. El código proporcionado lee líneas con dos números (un rectángulo) o uno (un cuadrado) e imprime square 2: area 4, perimeter 8.

Tu código va en Rectangle.R y Square.R. main.R contiene el código proporcionado de entrada/salida y no se puede editar.

Pruébalo tú mismo

source("Rectangle.R")
source("Square.R")

# Código de entrada/salida suministrado: mantenlo como está
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 = "")
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación orientada a objetos

Practica por tu cuenta: Compilador de R online