Klassenvektoren
Teil des Abschnitts Objektorientierte Programmierung der R-Journey von Coddy. Lektion 12 von 57.
Die S3-Vererbung ergibt sich aus dem Klassenvektor. Ein Objekt mit class = c("manager", "employee") ist ein Manager und auch ein Mitarbeiter. Wenn es für manager keine Methode für eine generische Funktion gibt, wird die Suche fortgesetzt und die Methode für employee verwendet:
pay <- function(x) UseMethod("pay")
pay.employee <- function(x) x$salary / 12
m <- structure(list(name = "Ada", salary = 60000), class = c("manager", "employee"))
print(class(m))
print(pay(m))Ausgabe:
[1] "manager" "employee"
[1] 5000Den Klassenvektor von Hand in jedem Konstruktor zu schreiben, wiederholt die Angaben des Elternteils. Stattdessen nimmt der Elternkonstruktor ein Argument class entgegen und stellt es vor seine eigene Klasse, und der Kindkonstruktor ruft den Elternkonstruktor auf:
new_employee <- function(name, salary, ..., class = character()) {
structure(list(name = name, salary = salary, ...), class = c(class, "employee"))
}
new_manager <- function(name, salary, reports) {
new_employee(name, salary, reports = reports, class = "manager")
}
m <- new_manager("Ada", 60000, 4)
print(class(m))
print(names(m))Ausgabe:
[1] "manager" "employee"
[1] "name" "salary" "reports"Das ... des Elternkonstruktors sammelt die zusätzlichen Felder des Kinds, hier reports, und fügt sie nach den eigenen Feldern des Elternteils ein. Ein einfacher Angestellter hat überhaupt kein Feld reports:
new_employee <- function(name, salary, ..., class = character()) {
structure(list(name = name, salary = salary, ...), class = c(class, "employee"))
}
e <- new_employee("Bo", 40000)
print(class(e))
print(names(e))Ausgabe:
[1] "employee"
[1] "name" "salary"Die Reihenfolge des Klassenvektors ist wichtig: Die spezifischste Klasse steht zuerst. Steht die Elternklasse an erster Stelle, greifen ihre Methoden und die Methoden der Kindklasse werden nie verwendet:
title <- function(x) UseMethod("title")
title.employee <- function(x) "employee"
title.manager <- function(x) "manager"
right <- structure(list(), class = c("manager", "employee"))
wrong <- structure(list(), class = c("employee", "manager"))
print(title(right))
print(title(wrong))Ausgabe:
[1] "manager"
[1] "employee"Aufgabe
EinfachMitarbeiter und Manager sind auf zwei Dateien aufgeteilt. Vervollständige new_employee(name, salary, ..., class = character()) in Employee.R: Die Funktion gibt eine Liste mit name, salary und allen zusätzlichen Feldern aus ... sowie dem Klassenvektor c(class, "employee") zurück. Vervollständige anschließend new_manager(name, salary, reports) in Manager.R. Diese Funktion ruft new_employee() mit dem zusätzlichen Feld reports und der Klasse manager auf.
label() und die zugehörige employee-Methode sind vorgegeben, sodass Manager eine Beschriftung erhalten, ohne eine eigene Methode zu haben. Der vorgegebene Code liest Zeilen wie employee Bo 40000 oder manager Ada 60000 4 und gibt den Klassenvektor, die Feldnamen und die Beschriftung aus.
Dein Code gehört in Employee.R und Manager.R. main.R enthält den vorgegebenen Ein-/Ausgabecode und kann nicht bearbeitet werden.
Probier es selbst
source("Employee.R")
source("Manager.R")
# Vorgegebener Ein-/Ausgabecode: unverändert lassen
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, " ")[[1]]
x <- if (p[1] == "manager") new_manager(p[2], as.numeric(p[3]), as.numeric(p[4])) else new_employee(p[2], as.numeric(p[3]))
cat("class: ", paste(class(x), collapse = ", "), "\n", sep = "")
cat("fields: ", paste(names(x), collapse = ", "), "\n", sep = "")
cat(label(x), "\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