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 das Generikum bereits, daher wird die Datei mit setGeneric() zuerst eingebunden. Ein Aufruf für eine Klasse ohne Methode bricht mit einem Fehler ab, 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
EinfachShapes sind S4-Klassen in drei Dateien. Erstelle in Shape.R die Generics area(shape) und perimeter(shape) mit setGeneric(), eingeschlossen in 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 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 darf nicht bearbeitet werden.
Probier es selbst
source("Shape.R")
source("Circle.R")
source("Square.R")
# Bereitgestellter Ein-/Ausgabe-Code: belasse ihn unverändert
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