Étendre avec NextMethod
Fait partie de la section Programmation orientée objet du Journey R de Coddy. Leçon 14 sur 57.
Une méthode enfant effectue souvent le travail du parent, avec un petit supplément. NextMethod() appelle la méthode parent, de sorte que l’enfant n’ajoute que ce qui est nouveau. La rémunération mensuelle d’un manager correspond à la rémunération d’un employé plus la prime :
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))Sortie :
3000 6000NextMethod() continue de fonctionner sur plusieurs niveaux. Chaque méthode ajoute sa partie et passe le relais à la classe qui suit la sienne :
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))Résultat :
[1] 12500Une méthode enfant peut également effectuer d'abord une vérification et ne transmettre l'appel que si la vérification réussit. La méthode du parent renvoie l'objet modifié avec son vecteur de classes complet, le résultat reste donc un compte d'épargne :
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))Sortie :
800 savings accountLes constructeurs et les méthodes réutilisent le parent de la même manière : new_manager() appelle new_employee(), et pay.manager() appelle NextMethod(). Le code de l’employé n’est écrit qu’une seule fois et chaque sous-classe s’appuie dessus :
new_manager <- function(name, salary, bonus) {
new_employee(name, salary, bonus = bonus, class = "manager") # réutiliser le constructeur
}
pay.manager <- function(x) NextMethod() + x$bonus / 12 # réutiliser la méthodeDéfi
FacileLes comptes et les comptes d’épargne se trouvent dans deux fichiers. Dans Account.R, complétez withdraw.account(acc, amount), qui s’arrête avec insufficient funds lorsque le montant est supérieur au solde et renvoie sinon le compte avec un solde inférieur, ainsi que format.account(), qui renvoie ada: 800. Dans Savings.R, complétez withdraw.savings(), qui s’arrête avec savings limit is 500 pour les montants supérieurs à 500 et transmet sinon l’appel avec NextMethod(), ainsi que format.savings(), qui renvoie ada: 800 (savings) en appelant NextMethod().
Utilisez call. = FALSE. Le générique et les constructeurs sont fournis. Le code fourni lit savings ada 1000 ou account bo 300, puis les montants à retirer ; il affiche withdrew 200 ou refused: suivi du message, puis le compte formaté.
Votre code doit être placé dans Account.R et Savings.R. main.R contient le code fourni pour les entrées et sorties et ne peut pas être modifié.
Essayez vous-même
source("Account.R")
source("Savings.R")
# Code d'entrée/sortie fourni : le garder tel quel
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 = "")
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation orientée objet
1Bases de S3
Travailler avec les fichiersListes avec une classeFonctions constructricesMéthodes print et formatValidateurs et fonctions utilitairesRécapitulatif - Températures4Encapsulation dans R
Les fermetures comme objetsLes environnements comme objetsFonctions d’accèsProtéger l’étatRécapitulatif - Parcmètre2S3 : génériques et méthodes
Génériques et UseMethodMéthodes par défautMéthodes pour les génériques de baseNotions de base sur NextMethodRécapitulatif - Aires des formes5Classes S4
Définir des classes S4Slots et accèsVérifications de validitéMéthodes showRécapitulatif - Catalogue de produits8Classes de référence
Définition des classes de référenceMéthodes et mises à jour des champsSémantique de copieHéritage et callSuperRécapitulatif - File d’attente des tâches11Projet : gestion de bibliothèque
Livres et membresEmprunter des livres3Héritage S3
Vecteurs de classesOrdre de recherche des méthodesÉtendre avec NextMethodVérifier avec inherits()Récapitulatif - Paie du personnelEntraînez-vous par vous-même : Compilateur R en ligne