Vecteurs de classes
Fait partie de la section Programmation orientée objet du Journey R de Coddy. Leçon 12 sur 57.
L’héritage S3 provient du vecteur de classes. Un objet avec class = c("manager", "employee") est un manager et aussi un employé. Lorsqu’un générique n’a pas de méthode pour manager, la recherche de méthode passe à la suite et utilise la méthode employee :
pay <- function(x) UseMethod("pay")
pay.employee <- function(x) x$salary / 12
m <- structure(list(name = "Ada", salary = 60000), class = c("manager", "employee"))
print(class(m))
print(pay(m))Résultat :
[1] "manager" "employee"
[1] 5000Écrire à la main le vecteur de classes dans chaque constructeur répète les détails de la classe parente. À la place, le constructeur parent prend un argument class et le place devant sa propre classe, et le constructeur enfant appelle celui du parent :
new_employee <- function(name, salary, ..., class = character()) {
structure(list(name = name, salary = salary, ...), class = c(class, "employee"))
}
new_manager <- function(name, salary, reports) {
new_employee(name, salary, reports = reports, class = "manager")
}
m <- new_manager("Ada", 60000, 4)
print(class(m))
print(names(m))Résultat :
[1] "manager" "employee"
[1] "name" "salary" "reports"Le ... du constructeur parent récupère les champs supplémentaires de l’enfant, ici reports, et les place après les propres champs du parent. Un employé ordinaire n’a pas du tout de champ reports :
new_employee <- function(name, salary, ..., class = character()) {
structure(list(name = name, salary = salary, ...), class = c(class, "employee"))
}
e <- new_employee("Bo", 40000)
print(class(e))
print(names(e))Résultat :
[1] "employee"
[1] "name" "salary"L’ordre du vecteur de classes est important : la classe la plus spécifique vient en premier. Si la classe parente vient en premier, ses méthodes l’emportent et celles de la classe enfant ne sont jamais utilisées :
title <- function(x) UseMethod("title")
title.employee <- function(x) "employee"
title.manager <- function(x) "manager"
right <- structure(list(), class = c("manager", "employee"))
wrong <- structure(list(), class = c("employee", "manager"))
print(title(right))
print(title(wrong))Résultat :
[1] "manager"
[1] "employee"Défi
FacileLes employés et les responsables sont répartis dans deux fichiers. Complétez new_employee(name, salary, ..., class = character()) dans Employee.R : cette fonction renvoie une liste contenant name, salary et tous les champs supplémentaires de ..., avec le vecteur de classes c(class, "employee"). Complétez ensuite new_manager(name, salary, reports) dans Manager.R : cette fonction appelle new_employee() avec le champ supplémentaire reports et la classe manager.
label() et sa méthode employee sont fournies ; les responsables obtiennent donc un libellé sans avoir leur propre méthode. Le code fourni lit des lignes employee Bo 40000 ou manager Ada 60000 4 et affiche le vecteur de classes, les noms des champs et le libellé.
Votre code doit être placé dans Employee.R et Manager.R. main.R contient le code d'entrée/sortie fourni et ne peut pas être modifié.
Essayez vous-même
source("Employee.R")
source("Manager.R")
# Code d'entrée/sortie fourni : conservez-le tel quel
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, " ")[[1]]
x <- if (p[1] == "manager") new_manager(p[2], as.numeric(p[3]), as.numeric(p[4])) else new_employee(p[2], as.numeric(p[3]))
cat("class: ", paste(class(x), collapse = ", "), "\n", sep = "")
cat("fields: ", paste(names(x), collapse = ", "), "\n", sep = "")
cat(label(x), "\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