Le système de classes S4 offre une approche plus formelle et rigoureuse de la programmation orientée objet en R. Les classes S4 sont définies explicitement à l’aide de la fonction
setClass()
Example 1 (Premier exemple)
Code
# Définition de la classe "personne"setClass(1"Personne",2slots =c(nom ="character", age ="numeric"))# Définition d'un constructeurPersonne <-function(nom, age) {# Vérification de la validité des donnéesif (!is.character(nom)) {stop("Le nom doit être une chaîne de caractères.") }if (!is.numeric(age) || age <0) {stop("L'âge doit être un nombre positif.") }# Création de l'objet "personne"3new("Personne", nom = nom, age = age)}
1
Nom de la classe
2
Spécifications des attributs (emplacements)
3
Instanciation dans le constructeur
Code
# Instancier un objet de classe PersonnePersonne("Jean", 57)
An object of class "Personne"
Slot "nom":
[1] "Jean"
Slot "age":
[1] 57
2 Emplacements (slots) et types de données
Dans les classes S4, les attributs sont appelés emplacements (slots). Chaque emplacement a un nom et un type de données spécifié. Cela permet une vérification stricte des types, ce qui rend le code plus robuste.
Example 2
Code
# Afficher les emplacements de la classe "personne"slotNames("Personne")
[1] "nom" "age"
Code
# Afficher les types des emplacementsgetClass("Personne")@slots
Les méthodes S4 sont définies à l’aide de la fonction setMethod(). Cette fonction permet de spécifier une fonction générique, la signature de la méthode (les types d’arguments) et le code de la méthode.
Example 3
Code
# Définition de la méthode générique 'print' pour la classe "Personne"setMethod(1"print",2"Personne",function(x) {cat("Personne :", x@nom, "\n")cat("Âge :", x@age, "ans\n")3 })# Création d'un objet "personne"john <-Personne(nom ="John Doe", age =30)# Appel de la fonction printprint(john)
1
Nom de la méthode générique
2
Nom de la classe concernée
3
Code de la méthode
Personne : John Doe
Âge : 30 ans
4 Accesseurs et Mutateurs
Les accesseurs et les mutateurs sont des méthodes spéciales qui permettent d’accéder aux emplacements (slots) d’un objet S4 de manière contrôlée. Ils sont particulièrement utiles pour :
Protéger les données internes de l’objet.
Effectuer des vérifications ou des transformations avant de renvoyer ou de modifier une valeur.
Fournir une interface plus conviviale pour l’accès en lecture ou en écriture aux emplacements.
Différence entre Accesseurs et Mutateurs
Accesseurs (getters) : Fonctions qui permettent d’accéder (en lecture) à un attribut d’un objet.
Mutateurs (setters) : Fonctions qui permettent de modifier un attribut d’un objet
Example 4 (Classe Cercle)
Code
# Définition de la classe CerclesetClass("Cercle",slots =list(rayon ="numeric",centre ="numeric" ))# Constructeur pour la classe CercleCercle <-function(rayon, centre =c(0, 0)) { # Centre par défaut à (0, 0)if (rayon <=0) {stop("Le rayon doit être un nombre positif.") }if (length(centre) !=2||!is.numeric(centre)) {stop("Le centre doit être un vecteur numérique de longueur 2.") }new("Cercle", rayon = rayon, centre = centre)}# Est ce Cercle?is.Cercle <-function(obj){is(obj, "Cercle")}# Accesseur (en lecture) pour le rayonsetGeneric("rayon", function(x) standardGeneric("rayon"))
[1] "rayon"
Code
setMethod("rayon", "Cercle", function(x) x@rayon)# Accesseur (en lecture) pour le centresetGeneric("centre", function(x) standardGeneric("centre"))
[1] "centre"
Code
setMethod("centre", "Cercle", function(x) x@centre)# Accesseur (en lecture) pour le diamètresetGeneric("diametre", function(x) standardGeneric("diametre"))
[1] "diametre"
Code
setMethod("diametre", "Cercle", function(x) 2*rayon(x))# Mutateur pour le rayon (avec vérification de validité)setGeneric("rayon<-", function(x, value) standardGeneric("rayon<-"))
[1] "rayon<-"
Code
setMethod("rayon<-", "Cercle", function(x, value) {if (value <=0) {stop("Le rayon doit être un nombre positif.") } x@rayon <- value x})# Mutateur pour le centre (avec vérification de validité)setGeneric("centre<-", function(x, value) standardGeneric("centre<-"))
[1] "centre<-"
Code
setMethod("centre<-", "Cercle", function(x, value) {if (length(value) !=2||!is.numeric(value)) {stop("Le centre doit être un vecteur numérique de longueur 2.") } x@centre <- value x})
Code
# Création d'un objet Cerclecercle1 <-Cercle(rayon =5, centre =c(1, 2))# Est-ce un Cercle?is.Cercle(cercle1)
[1] TRUE
Code
# Utilisation des accesseursrayon(cercle1)
[1] 5
Code
centre(cercle1)
[1] 1 2
Code
diametre(cercle1)
[1] 10
Code
# Utilisation des mutateursrayon(cercle1) <-7centre(cercle1) <-c(3, 4)# Une erreur# rayon(cercle1) <- -7# Affichage des valeurs mises à jourrayon(cercle1)
[1] 7
Code
centre(cercle1)
[1] 3 4
Code
diametre(cercle1)
[1] 14
Note
Noter la différence entre les accesseurs et les mutateurs!
5 Héritage en S4
S4 offre un mécanisme d’héritage formel et contrôlé. Une classe peut hériter des emplacements et des méthodes d’une autre classe.
Example 5
Code
# Définition de la classe "etudiant" qui hérite de "Personne"setClass("Etudiant",slots =c(matricule ="character"),contains ="Personne")# ConstructeurEtudiant <-function(nom, age, matricule){# Ajouter les contrôlesnew("Etudiant", nom = nom, age = age, matricule = matricule)}# Création d'un objet "etudiant"alice <-Etudiant(nom ="Alice Smith", age =20, matricule ="12345")# Appel de la fonction print (héritée de "Personne")print(alice)
Personne : Alice Smith
Âge : 20 ans
6 Exemples avancés et cas d’utilisation spécifiques
S4 est souvent utilisé pour :
Le développement de packages R nécessitant une grande fiabilité.
La modélisation de données complexes.
Les applications scientifiques et statistiques avancées.
7 Avantages et limites de S4
7.1 Avantages
Robustesse et sécurité accrues grâce à la vérification des types.
Meilleure organisation du code et plus grande clarté.
Gestion sophistiquée de l’héritage et de la distribution des méthodes.
7.2 Limites
Plus complexe et verbeux que S3 ou R6.
Peut être plus difficile à apprendre et à utiliser pour les débutants.
Dans la section suivante, nous explorerons le système de classes R6, qui offre une approche plus intuitive de la POO en R.
Bien sûr, voici une proposition de contenu au format Quarto pour la section “Les Classes R6 (POO Classique)” :