> langage et graphiques > Divers > Classes S3
Classes S3
Classes S3 : c'est la notion primitive des classes sous R.
Notion d'objet/classe en R :
- a été rajoutée après coup.
- a en plus été rajoutée sous deux formes (!) :
- classes S3 : consiste en un simple ajout d'un attribut class à un objet R existant. La notion centrale est celle de méthode, pas celle d'objet, et il n'y a pas d'encapsulation. C'est la forme la plus ancienne et elle est informelle.
- classes S4 : type plus sophistiqué et plus formel qui essaie de reproduire l'objet d'autres langages.
Principes des classes S3 :
- On définit des méthodes "génériques" grâce à UseMethod qui renvoie à la bonne implémentation en fonction de la classe du premier argument.
- Lors de l'appel de la méthode getArea, les différentes classes du premier argument sont examinées dans l'ordre, par exemple c("square", "rectangle").
- On cherche une fonction getArea.square().
- Si elle n'est pas trouvée, on cherche getArea.rectangle().
- Si elle n'est pas trouvée, on cherche getArea.default(), sinon, c'est une erreur.
- La première fonction trouvée est appelée avec les arguments additionnels éventuels.
Exemple :
getArea <- function(obj, scale = 1)
UseMethod("getArea", obj)
getArea.default <- function(obj, scale = 1) {
stop("Area not defined on any object")
}
getArea.circle <- function(obj, scale = 1) {
return(scale * pi * obj[2] ^ 2)
}
getArea.rectangle <- function(obj, scale = 1) {
return(scale * obj[1] * obj[2])
}
cir <- c(0, sqrt(10)); class(cir) <- "circle"
rec <- c(5, 6); class(rec) <- "rectangle"
squ <- c(3, 3); class(squ) <- c("square", "rectangle")
print(getArea(cir))
print(getArea(rec, 2))
print(getArea(squ))
Certaines fonctions sont déjà déclarées comme génériques : print(), length(), plot(), summary(), show() ...
C'est la méthode générique show qui appelée lorsque l'on affiche un objet (donc, si on veut changer l'apparence de l'affichage, il suffit de la redéfinir pour le type d'objet).
Examen des méthodes existantes :
- methods("summary") : liste toutes les fonctions summary existantes de type S3 et donc on a toutes les classes correspondantes (fonctions de type summary.*).
- methods(class = "factor") : liste toutes les fonctions existantes pour la classe factor (fonctions de type *.factor).
- getS3method("summary", "factor") : renvoie la fonction correspondante summary.factor (la fonction elle-même, pas son nom).
inherits : teste si un objet hérite de l'une des classes mentionnées : inherits(obj, c("class1", "class2")) : renvoie TRUE si obj fait partie d'au moins l'une des classes mentionnées.
Exemple de définition d'une classe S3, incluant de l'opérateur overloading :
## Constructor
String <- function(s) {
obj <- as.character(s)
class(obj) <- "String"
return(obj)
}
is.String <- function(obj) {
return(class(obj) == "String")
}
## Generic defined
print.String <- function(obj) {
return(paste("->", obj, "<-"))
}
## Generic defined
length.String <- function(obj) {
return(nchar(obj))
}
## Generic
numberOfLetter <- function(obj, letter)
UseMethod("numberOfLetter")
## Generic defined
numberOfLetter.String <- function(obj, letter) {
return(length(grep(letter, unlist(strsplit(obj, "")))))
}
## Operator overloading
"+.String" <- function(obj1, obj2) {
return(String(paste(obj1, obj2, sep = "")))
}
## Operator overloading
"[.String" <- function(obj, index) {
return(unclass(substr(obj, index + 1, index + 1)))
}
s <- String("essai de classe")
print(s)
print(length(s))
print(numberOfLetter(s, "a"))
s2 <- String("s")
print(s + s2)
print(s[4])
renvoie :
[1] "-> essai de classe <-"
[1] 15
[1] 2
[1] "-> essai de classes <-"
[1] "i"
Copyright Aymeric Duclert
programmer en R, tutoriel R, graphes en R