Génériques et UseMethod
Fait partie de la section Programmation orientée objet du Journey R de Coddy. Leçon 7 sur 57.
Un générique est une fonction dont le corps est UseMethod("name"). Lorsqu’elle est appelée, elle examine la classe de son premier argument et appelle la méthode name.class. print() et format() fonctionnent ainsi ; tu peux aussi écrire tes propres génériques :
speak <- function(x) UseMethod("speak")
speak.dog <- function(x) paste(x$name, "says woof")
speak.cat <- function(x) paste(x$name, "says meow")
rex <- structure(list(name = "Rex"), class = "dog")
tom <- structure(list(name = "Tom"), class = "cat")
print(speak(rex))
print(speak(tom))Résultat :
[1] "Rex says woof"
[1] "Tom says meow"L’appelant écrit un seul appel, et chaque objet répond à sa manière. C’est le polymorphisme : le code qui parcourt une liste mixte n’a pas besoin d’un if pour chaque classe :
speak <- function(x) UseMethod("speak")
speak.dog <- function(x) paste(x$name, "says woof")
speak.cat <- function(x) paste(x$name, "says meow")
pets <- list(structure(list(name = "Rex"), class = "dog"),
structure(list(name = "Tom"), class = "cat"),
structure(list(name = "Bo"), class = "dog"))
for (p in pets) cat(speak(p), "\n")Sortie :
Rex says woof
Tom says meow
Bo says woof Une méthode reçoit les arguments de la fonction générique. Donne à la fonction générique un paramètre ... afin que les méthodes puissent accepter leurs propres arguments supplémentaires, comme digits pour un cercle :
area <- function(shape, ...) UseMethod("area")
area.square <- function(shape, ...) shape$side^2
area.circle <- function(shape, digits = 2, ...) round(pi * shape$r^2, digits)
sq <- structure(list(side = 3), class = "square")
ci <- structure(list(r = 1), class = "circle")
print(area(sq))
print(area(ci))
print(area(ci, digits = 4))Résultat :
[1] 9
[1] 3.14
[1] 3.1416UseMethod() transmet l’appel à la méthode et ne revient jamais : quelle que soit la valeur renvoyée par la méthode, c’est le résultat de la fonction générique, et le code après UseMethod() ne s’exécute pas. Une fonction générique tient donc sur une ligne :
size <- function(x) {
UseMethod("size")
cat("this line never runs\n")
}
size.box <- function(x) x$w * x$h
b <- structure(list(w = 2, h = 5), class = "box")
print(size(b))Résultat :
[1] 10Défi
FacileLes formes sont réparties dans trois fichiers. Complète la fonction générique area() dans Shape.R, puis ajoute les méthodes area.circle() (pi multiplié par le rayon au carré) dans Circle.R et area.rectangle() (largeur multipliée par hauteur) dans Rectangle.R. Les constructeurs sont fournis.
Le code fourni lit les lignes circle 2 ou rectangle 3 4 et affiche la classe et l’aire de chaque forme avec deux décimales : circle: 12.57.
Ton code doit aller dans Shape.R, Circle.R et Rectangle.R. main.R contient le code fourni pour l’entrée/sortie et ne peut pas être modifié.
Essayez vous-même
source("Shape.R")
source("Circle.R")
source("Rectangle.R")
# Code d'entrée/sortie fourni : conservez-le tel quel
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, " ")[[1]]
s <- if (p[1] == "circle") new_circle(as.numeric(p[2])) else new_rectangle(as.numeric(p[2]), as.numeric(p[3]))
cat(sprintf("%s: %.2f", class(s), area(s)), "\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