Estendendo com NextMethod
Parte da seção Programação Orientada a Objetos do Journey de R da Coddy. Lição 14 de 57.
Um método filho geralmente faz o trabalho do pai e mais um pouco. NextMethod() chama o método pai, então o filho adiciona apenas o que é novo. O pagamento mensal de um gerente é o pagamento de um funcionário mais o bônus:
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))Saída:
3000 6000NextMethod() continua funcionando por vários níveis. Cada método adiciona sua parte e passa para a classe seguinte à sua:
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))Saída:
[1] 12500Um método filho também pode verificar primeiro e encaminhar apenas quando a verificação for aprovada. O método do pai retorna o objeto alterado com seu vetor de classes completo, portanto o resultado ainda é uma conta poupança:
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))Saída:
800 savings accountConstrutores e métodos reutilizam o pai da mesma forma: new_manager() chama new_employee(), e pay.manager() chama NextMethod(). O código de funcionário é escrito uma vez, e cada subclasse se baseia nele:
new_manager <- function(name, salary, bonus) {
new_employee(name, salary, bonus = bonus, class = "manager") # reutiliza o construtor
}
pay.manager <- function(x) NextMethod() + x$bonus / 12 # reutiliza o métodoDesafio
FácilContas e contas de poupança estão em dois arquivos. Em Account.R, complete withdraw.account(acc, amount), que interrompe com insufficient funds quando o valor está acima do saldo e, caso contrário, retorna a conta com o saldo reduzido, e format.account(), que retorna ada: 800. Em Savings.R, complete withdraw.savings(), que interrompe com savings limit is 500 para valores acima de 500 e, caso contrário, passa adiante com NextMethod(), e format.savings(), que retorna ada: 800 (savings) chamando NextMethod().
Use call. = FALSE. O genérico e os construtores são fornecidos. O código fornecido lê savings ada 1000 ou account bo 300, depois os valores a serem retirados; ele imprime withdrew 200 ou refused: e a mensagem e, por fim, a conta formatada.
Seu código deve ficar em Account.R e Savings.R. main.R contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
source("Account.R")
source("Savings.R")
# Código de entrada/saída fornecido: mantenha-o 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 lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos do S3
Trabalhando com ArquivosListas com uma ClasseFunções ConstrutorasMétodos de Impressão e FormataçãoValidadores e AuxiliaresRevisão - Temperaturas4Encapsulamento em R
Closures como ObjetosAmbientes como ObjetosFunções de AcessoProtegendo o EstadoRecapitulação - Parquímetro2Genéricos e Métodos S3
Genéricos e UseMethodMétodos padrãoMétodos para genéricos baseFundamentos de NextMethodRevisão - Áreas de formas5Classes S4
Definindo classes S4Slots e acessoVerificações de validadeMétodos showRevisão - Catálogo de produtos8Classes de Referência
Definindo Classes de ReferênciaMétodos e Atualizações de CamposSemântica de CópiaHerança e callSuperRecapitulação — Fila de Tarefas11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de Livros3Herança S3
Vetores de classeOrdem de busca de métodosEstendendo com NextMethodVerificando com inherits()Revisão - Folha de pagamento da equipePratique por conta própria: Compilador de R online