Generics erstellen
Teil des Abschnitts Objektorientierte Programmierung der R-Journey von Coddy. Lektion 27 von 57.
Ein S4-Generic wird mit setGeneric() erstellt. Sein Funktionskörper ist standardGeneric("name"), das S4-Gegenstück zu UseMethod(). setGeneric() gibt den Namen des Generics zurück, der ausgegeben wird, wenn es auf der obersten Ebene aufgerufen wird:
setGeneric("area", function(shape) standardGeneric("area"))Ausgabe:
[1] "area"Umschließe den Aufruf mit invisible(), damit diese Zeile nicht in der Ausgabe erscheint. setMethod("area", "Circle", ...) fügt dann die Methode für eine Klasse hinzu:
setClass("Circle", slots = c(r = "numeric"))
setClass("Square", slots = c(side = "numeric"))
invisible(setGeneric("area", function(shape) standardGeneric("area")))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
setMethod("area", "Square", function(shape) shape@side^2)
cat(area(new("Circle", r = 1)), area(new("Square", side = 3)))Ausgabe:
3.141593 9Eine Methode hat dieselben Argumente wie ihre generische Funktion. Wenn die generische Funktion ... enthält, kann eine Methode danach eigene benannte Argumente hinzufügen:
setClass("Circle", slots = c(r = "numeric"))
invisible(setGeneric("describe", function(x, ...) standardGeneric("describe")))
setMethod("describe", "Circle", function(x, ..., digits = 2) {
paste("circle of area", round(pi * x@r^2, digits))
})
c1 <- new("Circle", r = 2)
print(describe(c1))
print(describe(c1, digits = 4))Ausgabe:
[1] "circle of area 12.57"
[1] "circle of area 12.5664"setMethod() benötigt, dass das Generikum bereits existiert. Daher wird zuerst die Datei mit setGeneric() geladen. Ein Aufruf für eine Klasse ohne Methode wird mit einem Fehler abgebrochen, der die Signatur nennt:
invisible(setGeneric("area", function(shape) standardGeneric("area")))
setClass("Circle", slots = c(r = "numeric"))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
area(42)Ausgabe:
Error: unable to find an inherited method for function ‘area’ for signature ‘shape = "numeric"’
Execution haltedAufgabe
EinfachFormen sind S4-Klassen in drei Dateien. Erstelle in Shape.R die Generika area(shape) und perimeter(shape) mit setGeneric(), umschlossen von invisible(). In Circle.R und Square.R werden die Klassen deklariert; füge für jede Klasse die Methoden area und perimeter mit setMethod() hinzu.
Der bereitgestellte Code liest Zeilen wie circle 2 oder square 3 ein und gibt circle: area 12.57, perimeter 12.57 aus.
Dein Code gehört in Shape.R, Circle.R und Square.R. main.R enthält den bereitgestellten Ein-/Ausgabecode und kann nicht bearbeitet werden.
Probier es selbst
source("Shape.R")
source("Circle.R")
source("Square.R")
# Vorgegebener Ein-/Ausgabecode: unverändert lassen
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, " ")[[1]]
s <- if (p[1] == "circle") new("Circle", r = as.numeric(p[2])) else new("Square", side = as.numeric(p[2]))
cat(sprintf("%s: area %.2f, perimeter %.2f", p[1], area(s), perimeter(s)), "\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