Estendere con NextMethod
Fa parte della sezione Programmazione orientata agli oggetti del percorso R di Coddy. Lezione 14 di 57.
Un metodo figlio spesso svolge il lavoro del metodo genitore più qualcosa in più. NextMethod() chiama il metodo genitore, quindi il metodo figlio aggiunge solo ciò che è nuovo. La retribuzione mensile di un manager è la retribuzione di un dipendente più il bonus:
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))Risultato:
3000 6000NextMethod() continua a funzionare scendendo attraverso diversi livelli. Ogni metodo aggiunge la propria parte e passa la chiamata alla classe successiva:
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))Output:
[1] 12500Un metodo figlio può anche effettuare prima un controllo e passare il controllo al metodo successivo solo se ha esito positivo. Il metodo del genitore restituisce l’oggetto modificato con il suo vettore di classi completo, quindi il risultato è ancora un conto di risparmio:
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))Output:
800 savings accountI costruttori e i metodi riutilizzano la classe genitore allo stesso modo: new_manager() chiama new_employee() e pay.manager() chiama NextMethod(). Il codice per i dipendenti viene scritto una sola volta e ogni sottoclasse si basa su di esso:
new_manager <- function(name, salary, bonus) {
new_employee(name, salary, bonus = bonus, class = "manager") # riutilizza il costruttore
}
pay.manager <- function(x) NextMethod() + x$bonus / 12 # riutilizza il metodoSfida
FacileI conti e i conti di risparmio si trovano in due file. In Account.R completa withdraw.account(acc, amount), che si interrompe con insufficient funds quando l’importo supera il saldo e altrimenti restituisce il conto con il saldo ridotto, e format.account(), che restituisce ada: 800. In Savings.R completa withdraw.savings(), che si interrompe con savings limit is 500 per importi superiori a 500 e altrimenti prosegue con NextMethod(), e format.savings(), che restituisce ada: 800 (savings) chiamando NextMethod().
Usa call. = FALSE. La funzione generica e i costruttori sono forniti. Il codice fornito legge savings ada 1000 oppure account bo 300, poi gli importi da prelevare; stampa withdrew 200 oppure refused: e il messaggio, e infine il conto formattato.
Il tuo codice va inserito in Account.R e Savings.R. main.R contiene il codice fornito per l’input/output e non può essere modificato.
Provalo tu
source("Account.R")
source("Savings.R")
# Codice di input/output fornito: lascialo così com'è
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 = "")
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Nozioni di base su S3
Lavorare con i fileListe con una classeFunzioni costruttriciMetodi di stampa e formattazioneValidatori e funzioni di supportoRipasso - Temperature4Incapsulamento in R
Chiusure come oggettiAmbienti come oggettiFunzioni di accessoProteggere lo statoRiepilogo - Parcometro2Generics e metodi S3
Generics e UseMethodMetodi predefinitiMetodi per i generics di baseNozioni di base su NextMethodRiepilogo - Aree delle forme5Classi S4
Definire le classi S4Slot e accessoControlli di validitàMetodi showRiepilogo - Catalogo prodotti8Classi di riferimento
Definizione delle classi di riferimentoMetodi e aggiornamenti dei campiSemantica della copiaEreditarietà e callSuperRiepilogo - coda di attività11Progetto: Gestione della biblioteca
Libri e iscrittiPrestito dei libri3Ereditarietà S3
Vettori di classeOrdine di ricerca dei metodiEstendere con NextMethodVerificare con inherits()Riepilogo - Retribuzioni del personaleEsercitati da solo: Compilatore R online