Menu
Coddy logo textTech

Erweitern mit contains

Teil des Abschnitts Objektorientierte Programmierung der R-Journey von Coddy. Lektion 32 von 57.

contains = "Animal" macht eine neue S4-Klasse zu einer Unterklasse von Animal. Die Unterklasse hat jeden Slot ihres Elternteils sowie ihre eigenen Slots, und new() übernimmt sie alle:

setClass("Animal", slots = c(name = "character", age = "numeric"))
setClass("Dog", contains = "Animal", slots = c(breed = "character"))
rex <- new("Dog", name = "Rex", age = 3, breed = "collie")
print(slotNames("Dog"))
cat(rex@name, rex@breed)

Ausgabe:

[1] "breed" "name"  "age"  
Rex collie

Für das übergeordnete Objekt geschriebene Methoden funktionieren auch für das untergeordnete Objekt. Wenn ein Generic keine Methode für Dog hat, verwendet S4 diejenige für Animal:

setClass("Animal", slots = c(name = "character"))
setClass("Dog", contains = "Animal")
invisible(setGeneric("intro", function(a) standardGeneric("intro")))
setMethod("intro", "Animal", function(a) paste("I am", a@name))
print(intro(new("Dog", name = "Rex")))

Ausgabe:

[1] "I am Rex"

Eine Kindklasse überschreibt eine Methode der Elternklasse, indem sie für dasselbe Generikum eine eigene definiert. Die spezifischste Klasse gewinnt, und andere Unterklassen behalten die Methode der Elternklasse:

setClass("Animal", slots = c(name = "character"))
setClass("Dog", contains = "Animal")
setClass("Cat", contains = "Animal")
invisible(setGeneric("sound", function(a) standardGeneric("sound")))
setMethod("sound", "Animal", function(a) "...")
setMethod("sound", "Dog", function(a) "woof")
cat(sound(new("Dog", name = "Rex")), sound(new("Cat", name = "Tom")))

Ausgabe:

woof ...

is(x, "Animal") ist für einen Hund TRUE, und ein als "Animal" deklarierter Slot akzeptiert ein Dog. Code, der für die Elternklasse geschrieben wurde, funktioniert mit jeder Unterklasse:

setClass("Animal", slots = c(name = "character"))
setClass("Dog", contains = "Animal")
setClass("Owner", slots = c(pet = "Animal"))
rex <- new("Dog", name = "Rex")
o <- new("Owner", pet = rex)
cat(is(rex, "Animal"), is(o@pet, "Dog"))

Ausgabe:

TRUE TRUE
challenge icon

Aufgabe

Einfach

Mitarbeiter und Manager sind S4-Klassen in zwei Dateien. Employee.R deklariert Employee (Slots name, salary) und das generische describe() und benötigt eine Methode für Employee, die Bo earns 40000 zurückgibt. In Manager.R soll Manager deklariert werden, das Employee enthält und den Slot reports (numeric) hinzufügt; außerdem soll describe() überschrieben werden, sodass Ada earns 60000 and manages 4 zurückgegeben wird.

Der bereitgestellte Code liest Zeilen wie employee Bo 40000 oder manager Ada 60000 4 ein und gibt describe(), an, ob das Objekt ein Mitarbeiter ist, sowie seine Slots aus.

Dein Code gehört in Employee.R und Manager.R. main.R enthält den bereitgestellten Ein-/Ausgabecode und darf nicht bearbeitet werden.

Probier es selbst

source("Employee.R")
source("Manager.R")

# Bereitgestellter Input/Output-Code: belasse ihn wie er ist
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  x <- if (p[1] == "manager") {
    new("Manager", name = p[2], salary = as.numeric(p[3]), reports = as.numeric(p[4]))
  } else {
    new("Employee", name = p[2], salary = as.numeric(p[3]))
  }
  cat(describe(x), "\n", sep = "")
  cat("is an employee: ", is(x, "Employee"), ", slots: ", paste(slotNames(x), collapse = ", "), "\n", sep = "")
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-R-Compiler