Extensión con NextMethod
Parte de la sección Programación orientada a objetos del Journey de R de Coddy. Lección 14 de 57.
Un método hijo suele hacer el trabajo del padre y algo más. NextMethod() llama al método padre, por lo que el hijo solo añade lo nuevo. El pago mensual de un gerente es el pago de un empleado más la bonificación:
pay <- function(x) UseMethod("pay")
pay.employee <- function(x) x$salary / 12
pay.manager <- function(x) NextMethod() + x$bonus / 12
m <- structure(list(salary = 60000, bonus = 12000), class = c("manager", "employee"))
e <- structure(list(salary = 36000), class = "employee")
cat(pay(e), pay(m))Salida:
3000 6000NextMethod() sigue funcionando a través de varios niveles. Cada método añade su parte y pasa el control a la clase posterior a la suya:
pay <- function(x) UseMethod("pay")
pay.employee <- function(x) x$salary / 12
pay.manager <- function(x) NextMethod() + x$bonus / 12
pay.director <- function(x) NextMethod() + 500
d <- structure(list(salary = 120000, bonus = 24000),
class = c("director", "manager", "employee"))
print(pay(d))Salida:
[1] 12500Un método hijo también puede comprobar primero y delegar solo cuando la comprobación se supera. El método del padre devuelve el objeto modificado con su vector de clases completo, por lo que el resultado sigue siendo una cuenta de ahorros:
withdraw <- function(acc, amount) UseMethod("withdraw")
withdraw.account <- function(acc, amount) {
if (amount > acc$balance) stop("insufficient funds", call. = FALSE)
acc$balance <- acc$balance - amount
acc
}
withdraw.savings <- function(acc, amount) {
if (amount > 500) stop("savings limit is 500", call. = FALSE)
NextMethod()
}
s <- structure(list(balance = 1000), class = c("savings", "account"))
s <- withdraw(s, 200)
cat(s$balance, class(s))Salida:
800 savings accountLos constructores y los métodos reutilizan el elemento principal de la misma manera: new_manager() llama a new_employee(), y pay.manager() llama a NextMethod(). El código del empleado se escribe una vez y cada subclase se basa en él:
new_manager <- function(name, salary, bonus) {
new_employee(name, salary, bonus = bonus, class = "manager") # reutiliza el constructor
}
pay.manager <- function(x) NextMethod() + x$bonus / 12 # reutiliza el métodoDesafío
FácilLas cuentas y las cuentas de ahorro están en dos archivos. En Account.R, completa withdraw.account(acc, amount), que se detiene con insufficient funds cuando el importe supera el saldo y, en caso contrario, devuelve la cuenta con el saldo reducido, y format.account(), que devuelve ada: 800. En Savings.R, completa withdraw.savings(), que se detiene con savings limit is 500 para importes superiores a 500 y, en caso contrario, continúa con NextMethod(), y format.savings(), que devuelve ada: 800 (savings) llamando a NextMethod().
Usa call. = FALSE. El genérico y los constructores ya están proporcionados. El código proporcionado lee savings ada 1000 o account bo 300, después los importes que se deben retirar; imprime withdrew 200 o refused: y el mensaje, y finalmente la cuenta formateada.
Tu código va en Account.R y Savings.R. main.R contiene el código proporcionado de entrada y salida y no se puede editar.
Pruébalo tú mismo
source("Account.R")
source("Savings.R")
# Código de entrada/salida suministrado: déjalo tal como está
input <- suppressWarnings(readLines(file("stdin")))
p <- strsplit(input[1], " ")[[1]]
acc <- if (p[1] == "savings") new_savings(p[2], as.numeric(p[3])) else new_account(p[2], as.numeric(p[3]))
for (amount in as.numeric(input[-1])) {
acc <- tryCatch({
acc <- withdraw(acc, amount)
cat("withdrew ", amount, "\n", sep = "")
acc
}, error = function(e) {
cat("refused: ", conditionMessage(e), "\n", sep = "")
acc
})
}
cat(format(acc), "\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 personalPractica por tu cuenta: Compilador de R online