Menu
CoddyTech

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)

Résultat :

Ada is 36

setClass() renvoie également une fonction génératrice. Attribuez-la à un nom, généralement celui 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"))

Résultat :

[1] 8
[1] TRUE

Contrairement à S3, R vérifie les slots. Un slot inconnu ou une valeur du mauvais type interrompt new() avec une erreur ; un objet S4 a donc 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 n’est pas spécifié reçoit une valeur vide de son type, comme character(0). prototype définit plutôt des valeurs par défaut réelles. Le code plus ancien 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, et 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 les lignes title;author;pages, crée chaque livre avec new("Book", ...), affiche son étiquette, puis les noms des slots de la classe.

Votre code doit être placé dans Book.R. main.R contient le code d’entrée/sortie fourni et ne peut pas être modifié.

Essayez vous-même

source("Book.R")

# Code d'entrée/sortie fourni : conservez-le 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