Creación de genéricos
Parte de la sección Programación orientada a objetos del Journey de R de Coddy. Lección 27 de 57.
Un genérico S4 se crea con setGeneric(). Su cuerpo de función es standardGeneric("name"), la contraparte de S4 de UseMethod(). setGeneric() devuelve el nombre del genérico, que se imprime cuando se llama en el nivel superior:
setGeneric("area", function(shape) standardGeneric("area"))Salida:
[1] "area"Envuelve la llamada en invisible() para mantener esa línea fuera de la salida. setMethod("area", "Circle", ...) después añade el método para una clase:
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)))Salida:
3.141593 9Un método tiene los mismos argumentos que su genérico. Cuando el genérico tiene ..., un método puede añadir sus propios argumentos con nombre después de ellos:
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))Salida:
[1] "circle of area 12.57"
[1] "circle of area 12.5664"setMethod() necesita que el genérico ya exista, por lo que el archivo con setGeneric() se carga primero. Una llamada para una clase sin un método se detiene con un error que indica la firma:
invisible(setGeneric("area", function(shape) standardGeneric("area")))
setClass("Circle", slots = c(r = "numeric"))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
area(42)Salida:
Error: unable to find an inherited method for function ‘area’ for signature ‘shape = "numeric"’
Execution haltedDesafío
FácilLas formas son clases S4 en tres archivos. En Shape.R, crea los genéricos area(shape) y perimeter(shape) con setGeneric(), encapsulados en invisible(). En Circle.R y Square.R se declaran las clases; añade los métodos area y perimeter de cada una con setMethod().
El código proporcionado lee las líneas circle 2 o square 3 e imprime circle: area 12.57, perimeter 12.57.
Tu código va en Shape.R, Circle.R y Square.R. main.R contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
source("Shape.R")
source("Circle.R")
source("Square.R")
# Código de entrada/salida suministrado: déjalo tal como está
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 = "")
}
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
1Fundamentos de S3
Trabajar con archivosListas con una claseFunciones constructorasMétodos de impresión y formatoValidadores y auxiliaresRepaso: temperaturas4Encapsulación en R
Cierres como objetosEntornos como objetosFunciones de accesoProtección del estadoRepaso: parquímetro2S3 Genéricos y métodos
Genéricos y UseMethodMétodos predeterminadosMétodos para genéricos baseFundamentos de NextMethodRepaso: áreas de figuras5Clases S4
Definición de clases S4Slots y accesoComprobaciones de validezMétodos showRepaso - Catálogo de productos8Clases de referencia
Definición de clases de referenciaMétodos y actualizaciones de camposSemántica de copiaHerencia y callSuperRepaso: cola de tareas11Proyecto: Gestión de biblioteca
Libros y miembrosPréstamo de libros3Herencia en S3
Vectores de claseOrden de búsqueda de métodosExtensión con NextMethodComprobación con inherits()Repaso - Nómina del personal6S4 Genéricos y métodos
Creación de genéricosMétodos para funciones incorporadasDespacho sobre dos argumentossetValidity y validObjectRepaso: dinero y monedaPractica por tu cuenta: Compilador de R online