Menu
Coddy logo textTech

S4-Klassen definieren

Teil des Abschnitts Objektorientierte Programmierung der R-Journey von Coddy. Lektion 22 von 57.

S4 ist R's formales Objektsystem. setClass() deklariert eine Klasse mit benannten Slots und dem Typ jedes einzelnen, und new() erstellt ein Objekt. Der @-Operator liest einen Slot:

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

Ausgabe:

Ada is 36

setClass() gibt außerdem eine Generatorfunktion zurück. Weise sie einem Namen zu, normalerweise dem Klassennamen, und rufe sie wie einen Konstruktor auf:

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

Ausgabe:

[1] 8
[1] TRUE

Im Gegensatz zu S3 überprüft R die Slots. Ein unbekannter Slot oder ein Wert des falschen Typs beendet new() mit einem Fehler, sodass ein S4-Objekt immer die von seiner Klasse deklarierte Struktur hat:

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

Ausgabe:

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

Ein Slot, dem kein Wert zugewiesen wird, erhält einen leeren Wert seines Typs, wie etwa character(0). prototype legt stattdessen echte Standardwerte fest. Älterer Code deklariert die Slots mit representation(), was dasselbe wie slots bedeutet:

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))

Ausgabe:

[1] FALSE
[1] 0
challenge icon

Aufgabe

Einfach

Deklariere die S4-Klasse Book in Book.R mit drei Slots: title und author vom Typ character sowie pages vom Typ numeric. Vervollständige anschließend book_label(b), das die Slots mit @ ausliest und Dune by Frank Herbert (412 pages) zurückgibt.

Der bereitgestellte Code liest Zeilen im Format title;author;pages, erstellt jedes Buch mit new("Book", ...), gibt dessen Bezeichnung aus und schließlich die Slot-Namen der Klasse.

Dein Code gehört in Book.R. main.R enthält den bereitgestellten Ein-/Ausgabecode und kann nicht bearbeitet werden.

Probier es selbst

source("Book.R")

# Gelieferter Ein-/Ausgabecode: belasse ihn wie er ist
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 iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-R-Compiler