Menu
Coddy logo textTech

callNextMethod

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

Innerhalb einer S4-Methode ruft callNextMethod() die Methode der Elternklasse mit denselben Argumenten auf und gibt ihr Ergebnis zurück. Eine Methode der Kindklasse baut auf der Antwort der Elternklasse auf, anstatt sie zu wiederholen:

setClass("Employee", slots = c(name = "character", salary = "numeric"))
setClass("Manager", contains = "Employee", slots = c(reports = "numeric"))
invisible(setGeneric("describe", function(x) standardGeneric("describe")))
setMethod("describe", "Employee", function(x) paste(x@name, "earns", x@salary))
setMethod("describe", "Manager", function(x) paste(callNextMethod(), "and manages", x@reports))
print(describe(new("Manager", name = "Ada", salary = 60000, reports = 4)))

Ausgabe:

[1] "Ada earns 60000 and manages 4"

Das funktioniert auch für show(): Das Kind gibt die Zeilen des Elternteils und anschließend seine eigenen aus:

setClass("Employee", slots = c(name = "character"))
setClass("Manager", contains = "Employee", slots = c(reports = "numeric"))
setMethod("show", "Employee", function(object) cat("Employee:", object@name, "\n"))
setMethod("show", "Manager", function(object) {
  callNextMethod()
  cat("Reports:", object@reports, "\n")
})
new("Manager", name = "Ada", reports = 4)

Ausgabe:

Employee: Ada 
Reports: 4 

new() ruft das generische initialize() auf. Eine Methode dafür kann Slots ausfüllen, die aus anderen Werten abgeleitet werden. Sie ruft zuerst callNextMethod(.Object, ...) auf, sodass die normale Einrichtung und die Gültigkeitsprüfung weiterhin stattfinden:

setClass("Order", slots = c(prices = "numeric", total = "numeric"))
setMethod("initialize", "Order", function(.Object, ...) {
  .Object <- callNextMethod(.Object, ...)
  .Object@total <- sum(.Object@prices)
  .Object
})
o <- new("Order", prices = c(2.5, 4, 1))
print(o@total)

Ausgabe:

[1] 7.5

Wie NextMethod() in S3 verkettet callNextMethod() mehrere Ebenen, wobei jede Klasse ihren Teil hinzufügt:

setClass("Ticket", slots = c(base = "numeric"))
setClass("Vip", contains = "Ticket")
setClass("Backstage", contains = "Vip")
invisible(setGeneric("price", function(t) standardGeneric("price")))
setMethod("price", "Ticket", function(t) t@base)
setMethod("price", "Vip", function(t) callNextMethod() * 2)
setMethod("price", "Backstage", function(t) callNextMethod() + 50)
cat(price(new("Ticket", base = 30)), price(new("Vip", base = 30)), price(new("Backstage", base = 30)))

Ausgabe:

30 60 110
challenge icon

Aufgabe

Einfach

Tickets gibt es in drei Stufen, jede in einer eigenen Datei. Die Klassen und das generische price() sind deklariert. Füge die Methoden hinzu:

  • Ticket.R: price() entspricht dem Grundpreis; show() gibt Ticket for gala und eine neue Zeile aus.
  • Vip.R: price() entspricht dem 1,5-fachen Ticketpreis; show() gibt die Ticketzeile und anschließend VIP lounge access aus.
  • Backstage.R: price() entspricht dem VIP-Preis plus 50; show() gibt die VIP-Zeilen und anschließend Backstage pass aus.

Verwende callNextMethod() in den Methoden der Unterklassen. Der bereitgestellte Code liest Zeilen wie vip gala 80 (Stufe, Veranstaltung, Grundpreis) ein und gibt jedes Ticket sowie dessen Preis aus.

Dein Code gehört in Ticket.R, Vip.R und Backstage.R. main.R enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.

Probier es selbst

source("Ticket.R")
source("Vip.R")
source("Backstage.R")

# Bereitgestellter Ein-/Ausgabe-Code: belasse ihn unverändert
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  base <- as.numeric(p[3])
  t <- switch(p[1],
    standard = new("Ticket", event = p[2], base = base),
    vip = new("VipTicket", event = p[2], base = base),
    backstage = new("BackstageTicket", event = p[2], base = base))
  print(t)
  cat(sprintf("price: %.2f", price(t)), "\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