Classi virtuali
Fa parte della sezione Programmazione orientata agli oggetti del percorso R di Coddy. Lezione 34 di 57.
Una classe virtuale descrive ciò che una famiglia di classi ha in comune e non può avere oggetti propri. Dichiarala con representation("VIRTUAL"); le sue sottoclassi usano contains come di consueto:
setClass("Shape", representation("VIRTUAL"))
setClass("Circle", contains = "Shape", slots = c(r = "numeric"))
setClass("Square", contains = "Shape", slots = c(side = "numeric"))
cat(isVirtualClass("Shape"), is(new("Circle", r = 1), "Shape"), "\n")
cat(tryCatch({ new("Shape"); "made" }, error = function(e) "not allowed"), "\n")Output:
TRUE TRUE
not allowed Un metodo per la classe virtuale funziona per ogni sottoclasse. Qui describe() per Shape chiama area(), che viene implementato da ogni sottoclasse, quindi la descrizione viene scritta una sola volta:
setClass("Shape", representation("VIRTUAL"))
setClass("Circle", contains = "Shape", slots = c(r = "numeric"))
setClass("Square", contains = "Shape", slots = c(side = "numeric"))
invisible(setGeneric("area", function(s) standardGeneric("area")))
invisible(setGeneric("describe", function(s) standardGeneric("describe")))
setMethod("area", "Circle", function(s) pi * s@r^2)
setMethod("area", "Square", function(s) s@side^2)
setMethod("describe", "Shape", function(s) sprintf("%s with area %.2f", class(s), area(s)))
for (s in list(new("Circle", r = 1), new("Square", side = 2))) cat(describe(s), "\n")Output:
Circle with area 3.14
Square with area 4.00 Una classe virtuale può dichiarare degli slot, che ogni sottoclasse eredita:
setClass("Shape", representation("VIRTUAL", label = "character"))
setClass("Square", contains = "Shape", slots = c(side = "numeric"))
sq <- new("Square", label = "tile", side = 2)
print(slotNames("Square"))Output:
[1] "side" "label"setClassUnion() crea una classe virtuale a partire da classi esistenti. Uno slot di quel tipo accetta una qualunque di esse, come un contatto che sia un indirizzo email oppure un numero di telefono:
setClassUnion("Contact", c("character", "numeric"))
setClass("Friend", slots = c(name = "character", contact = "Contact"))
a <- new("Friend", name = "Ada", contact = "ada@x.org")
b <- new("Friend", name = "Bo", contact = 5550123)
cat(class(a@contact), class(b@contact), "\n")
cat(tryCatch({ new("Friend", name = "Cy", contact = TRUE); "ok" }, error = function(e) "refused"), "\n")Risultato:
character numeric
refused Sfida
FacileI pagamenti condividono la classe virtuale Payment (slot amount) e i generici fee() e receipt(), tutti in Payment.R. Completa:
- in
Payment.R, il metodoreceipt()perPayment:card: 100.00 + 2.00 fee, costruito a partire dal nome della classe in minuscolo, daamounte dafee(); - in
Card.R, la classeCard(che contienePayment) e il suofee(): il 2% dell’importo; - in
Cash.R, la classeCashe il suofee(): 0.
Il codice fornito legge righe card 100 o cash 20, stampa ogni ricevuta e il totale addebitato, quindi verifica che Payment sia virtuale e non possa essere creata.
Il tuo codice va in Payment.R, Card.R e Cash.R. main.R contiene il codice fornito per input/output e non può essere modificato.
Provalo tu
source("Payment.R")
source("Card.R")
source("Cash.R")
# Supplied input/output code: keep it as it is
input <- suppressWarnings(readLines(file("stdin")))
total <- 0
for (line in input) {
p <- strsplit(line, " ")[[1]]
amount <- as.numeric(p[2])
pay <- switch(p[1], card = new("Card", amount = amount), cash = new("Cash", amount = amount))
cat(receipt(pay), "\n", sep = "")
total <- total + amount + fee(pay)
}
cat(sprintf("charged: %.2f", total), "\n", sep = "")
cat("Payment is virtual: ", isVirtualClass("Payment"), "\n", sep = "")
cat(tryCatch({ new("Payment", amount = 1); "created a Payment" }, error = function(e) "cannot create a Payment"), "\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 - Parcometro7S4 Ereditarietà
Estendere con containscallNextMethodClassi virtualiVerificare i tipi con is()Riepilogo - Guardiano dello zoo2Generics 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