Menu
Coddy logo textTech

Définir des classes S4

Fait partie de la section Programmation orientée objet du Journey R de Coddy. Leçon 22 sur 57.

S4 est le système formel d’objets de R. setClass() déclare une classe avec des slots nommés et le type de chacun, et new() crée un objet. L’opérateur @ lit un slot :

setClass("Person", slots = c(name = "character", age = "numeric"))
ada <- new("Person", name = "Ada", age = 36)
cat(ada@name, "is", ada@age)

Sortie :

Ada is 36

setClass() renvoie également une fonction génératrice. Attribuez-la à un nom, généralement le nom de la classe, et appelez-la comme un constructeur :

Person <- setClass("Person", slots = c(name = "character", age = "numeric"))
bo <- Person(name = "Bo", age = 7)
print(bo@age + 1)
print(is(bo, "Person"))

Sortie :

[1] 8
[1] TRUE

Contrairement à S3, R vérifie les slots. Un slot inconnu ou une valeur du mauvais type arrête new() avec une erreur, de sorte qu’un objet S4 a toujours la structure déclarée par sa classe :

setClass("Person", slots = c(name = "character", age = "numeric"))
p <- new("Person", name = "Cy", age = "ten")

Sortie :

Error in validObject(.Object) : 
  invalid class “Person” object: invalid object for slot "age" in class "Person": got class "character", should be or extend class "numeric"
Calls: new -> initialize -> initialize -> validObject
Execution halted

Un slot qui ne reçoit aucune valeur obtient une valeur vide de son type, comme character(0). prototype définit à la place de véritables valeurs par défaut. L’ancien code déclare les slots avec representation(), ce qui signifie la même chose que slots :

setClass("Task", slots = c(title = "character", done = "logical"),
         prototype = list(done = FALSE))
setClass("Note", representation(text = "character"))
t <- new("Task", title = "Write report")
print(t@done)
print(length(new("Note")@text))

Sortie :

[1] FALSE
[1] 0
challenge icon

Défi

Facile

Déclarez la classe S4 Book dans Book.R avec trois slots : title et author de type character, ainsi que pages de type numeric. Complétez ensuite book_label(b), qui lit les slots avec @ et renvoie Dune by Frank Herbert (412 pages).

Le code fourni lit des lignes au format title;author;pages, crée chaque livre avec new("Book", ...), affiche son libellé, puis affiche enfin les noms des slots de la classe.

Votre code doit être placé dans Book.R. main.R contient le code fourni pour les entrées et sorties et ne peut pas être modifié.

Essayez vous-même

source("Book.R")

# Code d'entrée/sortie fourni : le garder tel quel
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, ";")[[1]]
  b <- new("Book", title = p[1], author = p[2], pages = as.numeric(p[3]))
  cat(book_label(b), "\n", sep = "")
}
cat("slots: ", paste(slotNames("Book"), collapse = ", "), "\n", sep = "")
quiz iconTestez-vous

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

Entraînez-vous par vous-même : Compilateur R en ligne