Menu
Coddy logo textTech

Grundlagen von NextMethod

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

Innerhalb einer Methode ruft NextMethod() die nächste Methode in der Reihenfolge für dasselbe generische Objekt mit denselben Argumenten auf. Bei einem Objekt mit einer Klasse ist die nächste Methode die Standardmethode, sodass eine Methode die allgemeine Antwort wiederverwenden und ergänzen kann:

describe <- function(x) UseMethod("describe")
describe.default <- function(x) paste("an object with", length(x), "fields")
describe.task <- function(x) paste0(NextMethod(), ", titled ", x$title)
t <- structure(list(title = "Buy milk", done = FALSE), class = "task")
print(describe(t))

Ausgabe:

[1] "an object with 2 fields, titled Buy milk"

Ein Objekt kann mehrere Klassen in einem Vektor haben, etwa c("urgent", "task"). Beim Dispatch werden sie der Reihe nach ausprobiert, und NextMethod() in der ersten Methode fährt mit der Methode für die nächste Klasse fort:

describe <- function(x) UseMethod("describe")
describe.task <- function(x) paste("task:", x$title)
describe.urgent <- function(x) paste("URGENT", NextMethod())
fix <- structure(list(title = "Fix the leak"), class = c("urgent", "task"))
print(describe(fix))

Ausgabe:

[1] "URGENT task: Fix the leak"

NextMethod() gibt jedes Argument weiter, das die Methode erhalten hat, einschließlich zusätzlicher Argumente wie sep. Die nächste Methode sieht dieselben Werte, ohne dass du sie erneut auflisten musst:

label <- function(x, sep = ": ") UseMethod("label")
label.default <- function(x, sep = ": ") paste0("item", sep, x$name)
label.box <- function(x, sep = ": ") paste0("[", NextMethod(), "]")
b <- structure(list(name = "tools"), class = "box")
print(label(b))
print(label(b, sep = " = "))

Ausgabe:

[1] "[item: tools]"
[1] "[item = tools]"

Base R verwendet NextMethod(), um eine Klasse beizubehalten, wenn ein Vektor eine Teilmenge bildet. Das standardmäßige [ entfernt die Klasse, daher ermöglicht eine "[.percent"-Methode, dass es die Arbeit erledigt und die Klasse wieder hinzufügt:

format.percent <- function(x, ...) paste0(unclass(x) * 100, "%")
"[.percent" <- function(x, i) structure(NextMethod(), class = "percent")
p <- structure(c(0.1, 0.25, 0.5), class = "percent")
print(format(p[2:3]))

Ausgabe:

[1] "25%" "50%"
challenge icon

Aufgabe

Einfach

Tasks und dringende Tasks sind zwei Klassen in zwei Dateien. Vervollständige in Task.R das generische describe(), die Standardmethode, die an item zurückgibt, sowie describe.task(), die durch den Aufruf von NextMethod() und das Hinzufügen des Titels an item: Buy milk zurückgibt. Vervollständige in Urgent.R describe.urgent(), die durch den Aufruf von NextMethod() URGENT an item: Fix bug zurückgibt.

Die Konstruktoren sind vorgegeben: Ein dringender Task hat die Klasse c("urgent", "task"). Der bereitgestellte Code liest die Zeilen task Buy milk, urgent Fix bug oder ein beliebiges anderes Wort mit einem Titel ein, der zu einem Objekt dieser Klasse wird, und gibt für jedes Objekt describe() aus.

Dein Code gehört in Task.R und Urgent.R. main.R enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.

Probier es selbst

source("Task.R")
source("Urgent.R")

# Bereitgestellter Ein-/Ausgabecode: belasse ihn wie er ist
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  kind <- sub(" .*", "", line)
  title <- sub("^[a-z]+ ", "", line)
  t <- if (kind == "urgent") new_urgent(title) else if (kind == "task") new_task(title) else structure(list(title = title), class = kind)
  cat(describe(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