Creare generici
Fa parte della sezione Programmazione orientata agli oggetti del percorso R di Coddy. Lezione 27 di 57.
Un generico S4 viene creato con setGeneric(). Il suo corpo della funzione è standardGeneric("name"), la controparte S4 di UseMethod(). setGeneric() restituisce il nome del generico, che viene stampato quando viene chiamato al livello superiore:
setGeneric("area", function(shape) standardGeneric("area"))Output:
[1] "area"Racchiudi la chiamata in invisible() per escludere quella riga dall'output. setMethod("area", "Circle", ...) aggiunge quindi il metodo per una classe:
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)))Output:
3.141593 9Un metodo ha gli stessi argomenti del suo generico. Quando il generico ha ..., un metodo può aggiungere i propri argomenti con nome dopo di essi:
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))Output:
[1] "circle of area 12.57"
[1] "circle of area 12.5664"setMethod() richiede che il generico esista già, quindi il file con setGeneric() viene caricato per primo. Una chiamata per una classe senza un metodo si interrompe con un errore che indica la firma:
invisible(setGeneric("area", function(shape) standardGeneric("area")))
setClass("Circle", slots = c(r = "numeric"))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
area(42)Output:
Error: unable to find an inherited method for function ‘area’ for signature ‘shape = "numeric"’
Execution haltedSfida
FacileLe forme sono classi S4 in tre file. In Shape.R crea i generici area(shape) e perimeter(shape) con setGeneric(), racchiusi in invisible(). In Circle.R e Square.R vengono dichiarate le classi; aggiungi i metodi area e perimeter di ciascuna con setMethod().
Il codice fornito legge righe circle 2 o square 3 e stampa circle: area 12.57, perimeter 12.57.
Il tuo codice va in Shape.R, Circle.R e Square.R. main.R contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
source("Shape.R")
source("Circle.R")
source("Square.R")
# Código de entrada/salida proporcionado: déjalo tal como está
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 = "")
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Nozioni di base su S3
Lavorare con i fileListe con una classeFunzioni costruttriciMetodi di stampa e formattazioneValidatori e funzioni di supportoRipasso - Temperature4Incapsulamento in R
Chiusure come oggettiAmbienti come oggettiFunzioni di accessoProteggere lo statoRiepilogo - Parcometro2Generics e metodi S3
Generics e UseMethodMetodi predefinitiMetodi per i generics di baseNozioni di base su NextMethodRiepilogo - Aree delle forme5Classi S4
Definire le classi S4Slot e accessoControlli di validitàMetodi showRiepilogo - Catalogo prodotti8Classi di riferimento
Definizione delle classi di riferimentoMetodi e aggiornamenti dei campiSemantica della copiaEreditarietà e callSuperRiepilogo - coda di attività11Progetto: Gestione della biblioteca
Libri e iscrittiPrestito dei libriEsercitati da solo: Compilatore R online