Menu
CoddyTech

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 alle Slots ihrer Elternklasse sowie ihre eigenen, 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 die übergeordnete Klasse geschriebene Methoden funktionieren auch für die untergeordnete Klasse. Wenn es für Dog keine Methode für einen generischen Namen gibt, 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"

Ein Kind überschreibt eine Methode der Elternklasse, indem es eine eigene für dasselbe Generikum definiert. Die spezifischste Klasse gewinnt, und andere Unterklassen behalten die Methode der Elternklasse bei:

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 Slot, der als "Animal" deklariert ist, 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 Generikum describe(); außerdem wird eine Methode für Employee benötigt, die Bo earns 40000 zurückgibt. Deklariere in Manager.R Manager, das Employee enthält und den Slot reports (numeric) hinzufügt, und überschreibe describe(), sodass es Ada earns 60000 and manages 4 zurückgibt.

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

Dein Code gehört in Employee.R und Manager.R. main.R enthält den bereitgestellten 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", 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