Konstruktorfunktionen
Teil des Abschnitts Objektorientierte Programmierung der R-Journey von Coddy. Lektion 3 von 57.
Da R die Felder eines S3-Objekts niemals überprüft, sollte jedes Objekt einer Klasse von einer einzigen Funktion erstellt werden, ihrem Konstruktor. Konventionell wird der Konstruktor auf niedriger Ebene new_ plus dem Klassennamen genannt. Er nimmt jedes Feld als Argument entgegen, überprüft die Typen mit stopifnot() und gibt das Objekt zurück:
new_money <- function(amount = double(), currency = character()) {
stopifnot(is.double(amount), is.character(currency))
structure(list(amount = amount, currency = currency), class = "money")
}
m <- new_money(9.5, "EUR")
cat(m$amount, m$currency)Ausgabe:
9.5 EURstopifnot() beendet das Programm, wenn eine seiner Bedingungen nicht TRUE ist, und die Meldung benennt die fehlgeschlagene Prüfung. Ein falscher Typ wird in dem Moment erkannt, in dem das Objekt erstellt wird, und nicht erst später, wenn eine andere Funktion es verwendet:
new_money <- function(amount = double(), currency = character()) {
stopifnot(is.double(amount), is.character(currency))
structure(list(amount = amount, currency = currency), class = "money")
}
m <- new_money("9.5", "EUR")Ausgabe:
Error in new_money("9.5", "EUR") : is.double(amount) is not TRUE
Calls: new_money -> stopifnot
Execution haltedDer Konstruktor ist der einzige Ort, der structure() für die Klasse aufruft, sodass jedes Objekt dieselben Felder in derselben Reihenfolge hat. Code, der viele Objekte benötigt, ruft ihn in einer Schleife oder mit lapply() auf:
new_point <- function(x = 0, y = 0) {
stopifnot(is.numeric(x), is.numeric(y))
structure(list(x = x, y = y), class = "point")
}
pts <- lapply(1:3, function(i) new_point(i, i * i))
for (p in pts) cat(p$x, p$y, "\n")Ausgabe:
1 1
2 4
3 9 Ein S3-Objekt muss keine Liste sein. Ein Konstruktor kann einen einfachen Vektor kennzeichnen und zusätzliche Informationen als Attribute speichern – so funktionieren auch R-eigene Faktoren und Datumsangaben. attr(x, "unit") liest ein Attribut:
new_distance <- function(value = double(), unit = "m") {
stopifnot(is.double(value), is.character(unit))
structure(value, unit = unit, class = "distance")
}
d <- new_distance(c(1.5, 2), "km")
print(attr(d, "unit"))
print(unclass(d)[2] * 1000)Ausgabe:
[1] "km"
[1] 2000Aufgabe
EinfachVervollständige den Konstruktor new_book(title, author, pages) in Book.R. Er prüft mit stopifnot(), dass title und author Zeichenketten und pages numerisch ist, und gibt eine Liste mit diesen drei Feldern und der Klasse book zurück. Vervollständige anschließend book_label(b), das Dune by Frank Herbert, 412 pages zurückgibt.
Der bereitgestellte Code liest Zeilen im Format title;author;pages. Er übergibt pages als Zahl, wenn der Wert nur aus Ziffern besteht, und andernfalls als ursprünglichen Text, gibt book: und die Bezeichnung für jedes Objekt aus und gibt rejected: sowie den Titel aus, wenn der Konstruktor abbricht.
Dein Code gehört in Book.R. main.R enthält den bereitgestellten Eingabe-/Ausgabecode und kann nicht bearbeitet werden.
Probier es selbst
source("Book.R")
# Mitgelieferter Ein-/Ausgabe-Code: belasse ihn unverändert
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, ";")[[1]]
pages <- if (grepl("^[0-9]+$", p[3])) as.numeric(p[3]) else p[3]
b <- tryCatch(new_book(p[1], p[2], pages), error = function(e) NULL)
if (is.null(b)) {
cat("rejected: ", p[1], "\n", sep = "")
} else {
cat(class(b), ": ", book_label(b), "\n", sep = "")
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1S3-Grundlagen
Arbeiten mit DateienListen mit einer KlasseKonstruktorfunktionenPrint- und Format-MethodenValidatoren und HilfsfunktionenRückblick – Temperaturen4Kapselung in R
Closures als ObjekteUmgebungen als ObjekteZugriffsfunktionenZustand schützenRückblick – Parkuhr2S3-Generics und Methoden
Generics und UseMethodStandardmethodenMethoden für Basis-GenericsGrundlagen von NextMethodWiederholung – Flächeninhalte von Formen5S4-Klassen
S4-Klassen definierenSlots und ZugriffGültigkeitsprüfungenShow-MethodenRückblick – Produktkatalog8Referenzklassen
Referenzklassen definierenMethoden und FeldänderungenKopiersemantikVererbung und callSuperZusammenfassung – Aufgabenwarteschlange11Projekt: Bibliotheksverwaltung
Bücher und MitgliederBücher ausleihenÜbe selbstständig: Online-R-Compiler