Clases virtuales
Parte de la sección Programación orientada a objetos del Journey de R de Coddy. Lección 34 de 57.
Una clase virtual describe lo que una familia de clases tiene en común y no puede tener objetos propios. Declárala con representation("VIRTUAL"); sus subclases usan contains como de costumbre:
setClass("Shape", representation("VIRTUAL"))
setClass("Circle", contains = "Shape", slots = c(r = "numeric"))
setClass("Square", contains = "Shape", slots = c(side = "numeric"))
cat(isVirtualClass("Shape"), is(new("Circle", r = 1), "Shape"), "\n")
cat(tryCatch({ new("Shape"); "made" }, error = function(e) "not allowed"), "\n")Salida:
TRUE TRUE
not allowed Un método para la clase virtual funciona para cada subclase. Aquí, describe() para Shape llama a area(), que cada subclase implementa, por lo que la descripción se escribe una sola vez:
setClass("Shape", representation("VIRTUAL"))
setClass("Circle", contains = "Shape", slots = c(r = "numeric"))
setClass("Square", contains = "Shape", slots = c(side = "numeric"))
invisible(setGeneric("area", function(s) standardGeneric("area")))
invisible(setGeneric("describe", function(s) standardGeneric("describe")))
setMethod("area", "Circle", function(s) pi * s@r^2)
setMethod("area", "Square", function(s) s@side^2)
setMethod("describe", "Shape", function(s) sprintf("%s with area %.2f", class(s), area(s)))
for (s in list(new("Circle", r = 1), new("Square", side = 2))) cat(describe(s), "\n")Salida:
Circle with area 3.14
Square with area 4.00 Una clase virtual puede declarar slots, que después tiene cada subclase:
setClass("Shape", representation("VIRTUAL", label = "character"))
setClass("Square", contains = "Shape", slots = c(side = "numeric"))
sq <- new("Square", label = "tile", side = 2)
print(slotNames("Square"))Salida:
[1] "side" "label"setClassUnion() crea una clase virtual a partir de clases existentes. Un slot de ese tipo acepta cualquiera de ellas, como un contacto que puede ser una dirección de correo electrónico o un número de teléfono:
setClassUnion("Contact", c("character", "numeric"))
setClass("Friend", slots = c(name = "character", contact = "Contact"))
a <- new("Friend", name = "Ada", contact = "ada@x.org")
b <- new("Friend", name = "Bo", contact = 5550123)
cat(class(a@contact), class(b@contact), "\n")
cat(tryCatch({ new("Friend", name = "Cy", contact = TRUE); "ok" }, error = function(e) "refused"), "\n")Salida:
character numeric
refused Desafío
FácilLos pagos comparten la clase virtual Payment (ranura amount) y los genéricos fee() y receipt(), todos en Payment.R. Completa:
- en
Payment.R, el métodoreceipt()paraPayment:card: 100.00 + 2.00 fee, construido a partir del nombre de la clase en minúsculas,amountyfee(); - en
Card.R, la claseCard(que contienePayment) y sufee(): el 2 % del importe; - en
Cash.R, la claseCashy sufee(): 0.
El código proporcionado lee líneas card 100 o cash 20, imprime cada recibo y el total cobrado, y después comprueba que Payment es virtual y no se puede crear.
Tu código va en Payment.R, Card.R y Cash.R. main.R contiene el código de entrada/salida proporcionado y no se puede editar.
Pruébalo tú mismo
source("Payment.R")
source("Card.R")
source("Cash.R")
# Código de entrada/salida suministrado: mantenlo tal como está
input <- suppressWarnings(readLines(file("stdin")))
total <- 0
for (line in input) {
p <- strsplit(line, " ")[[1]]
amount <- as.numeric(p[2])
pay <- switch(p[1], card = new("Card", amount = amount), cash = new("Cash", amount = amount))
cat(receipt(pay), "\n", sep = "")
total <- total + amount + fee(pay)
}
cat(sprintf("charged: %.2f", total), "\n", sep = "")
cat("Payment is virtual: ", isVirtualClass("Payment"), "\n", sep = "")
cat(tryCatch({ new("Payment", amount = 1); "created a Payment" }, error = function(e) "cannot create a Payment"), "\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ímetro7S4 Herencia
Extender con containscallNextMethodClases virtualesComprobar tipos con is()Repaso - Cuidador del zoológico2S3 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 librosPractica por tu cuenta: Compilador de R online