Virtuelle Klassen
Teil des Abschnitts Objektorientierte Programmierung der R-Journey von Coddy. Lektion 34 von 57.
Eine virtuelle Klasse beschreibt, was eine Familie von Klassen gemeinsam hat, und kann keine eigenen Objekte haben. Deklariere sie mit representation("VIRTUAL"); ihre Unterklassen verwenden contains wie gewohnt:
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")Ausgabe:
TRUE TRUE
not allowed Eine Methode für die virtuelle Klasse funktioniert für jede Unterklasse. Hier ruft describe() für Shape area() auf, das jede Unterklasse implementiert, sodass die Beschreibung nur einmal geschrieben wird:
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")Ausgabe:
Circle with area 3.14
Square with area 4.00 Eine virtuelle Klasse kann Slots deklarieren, die dann jede Unterklasse besitzt:
setClass("Shape", representation("VIRTUAL", label = "character"))
setClass("Square", contains = "Shape", slots = c(side = "numeric"))
sq <- new("Square", label = "tile", side = 2)
print(slotNames("Square"))Ausgabe:
[1] "side" "label"setClassUnion() erstellt aus vorhandenen Klassen eine virtuelle Klasse. Ein Slot dieses Typs akzeptiert jede dieser Klassen, etwa einen Kontakt, der entweder eine E-Mail-Adresse oder eine Telefonnummer ist:
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")Ausgabe:
character numeric
refused Aufgabe
EinfachPayments teilen die virtuelle Klasse Payment (Slot amount) und die Generics fee() und receipt(), alle in Payment.R. Vervollständige:
- in
Payment.Rdiereceipt()-Methode fürPayment:card: 100.00 + 2.00 fee, erstellt aus dem kleingeschriebenen Klassennamen,amountundfee(); - in
Card.Rdie KlasseCard(enthältPayment) und ihrfee(): 2 % des Betrags; - in
Cash.Rdie KlasseCashund ihrfee(): 0.
Der bereitgestellte Code liest Zeilen card 100 oder cash 20, gibt jede Quittung und den insgesamt berechneten Betrag aus und prüft anschließend, dass Payment virtuell ist und nicht erstellt werden kann.
Dein Code gehört in Payment.R, Card.R und Cash.R. main.R enthält den bereitgestellten Ein-/Ausgabecode und kann nicht bearbeitet werden.
Probier es selbst
source("Payment.R")
source("Card.R")
source("Cash.R")
# Bereitgestellter Ein-/Ausgabe-Code: belasse ihn wie er ist
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 = "")
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 – Parkuhr7S4-Vererbung
Erweitern mit containscallNextMethodVirtuelle KlassenTypen mit is() prüfenRückblick – Zoowärter2S3-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