Generics i UseMethod
Część sekcji Programowanie obiektowe ścieżki R w Coddy. Lekcja 7 z 57.
Funkcja ogólna to funkcja, której ciało zawiera UseMethod("name"). Gdy zostanie wywołana, sprawdza klasę swojego pierwszego argumentu i wywołuje metodę name.class. print() i format() działają w ten sposób; możesz też napisać własne funkcje ogólne:
speak <- function(x) UseMethod("speak")
speak.dog <- function(x) paste(x$name, "says woof")
speak.cat <- function(x) paste(x$name, "says meow")
rex <- structure(list(name = "Rex"), class = "dog")
tom <- structure(list(name = "Tom"), class = "cat")
print(speak(rex))
print(speak(tom))Wynik:
[1] "Rex says woof"
[1] "Tom says meow"Wywołujący wykonuje jedno wywołanie, a każdy obiekt odpowiada na swój sposób. To jest polimorfizm: kod, który iteruje po mieszanej liście, nie potrzebuje instrukcji if dla każdej klasy:
speak <- function(x) UseMethod("speak")
speak.dog <- function(x) paste(x$name, "says woof")
speak.cat <- function(x) paste(x$name, "says meow")
pets <- list(structure(list(name = "Rex"), class = "dog"),
structure(list(name = "Tom"), class = "cat"),
structure(list(name = "Bo"), class = "dog"))
for (p in pets) cat(speak(p), "\n")Wynik:
Rex says woof
Tom says meow
Bo says woof Metoda przyjmuje argumenty funkcji generycznej. Dodaj do funkcji generycznej parametr ..., aby metody mogły przyjmować własne dodatkowe argumenty, takie jak digits w przypadku koła:
area <- function(shape, ...) UseMethod("area")
area.square <- function(shape, ...) shape$side^2
area.circle <- function(shape, digits = 2, ...) round(pi * shape$r^2, digits)
sq <- structure(list(side = 3), class = "square")
ci <- structure(list(r = 1), class = "circle")
print(area(sq))
print(area(ci))
print(area(ci, digits = 4))Wynik:
[1] 9
[1] 3.14
[1] 3.1416UseMethod() przekazuje wywołanie metodzie i nigdy nie wraca: cokolwiek zwróci metoda, jest wynikiem funkcji ogólnej, a kod po UseMethod() nie zostaje uruchomiony. Funkcja ogólna składa się więc z jednego wiersza:
size <- function(x) {
UseMethod("size")
cat("this line never runs\n")
}
size.box <- function(x) x$w * x$h
b <- structure(list(w = 2, h = 5), class = "box")
print(size(b))Wynik:
[1] 10Wyzwanie
ŁatwyDefinicje kształtów są podzielone na trzy pliki. Uzupełnij generyczną funkcję area() w pliku Shape.R, a następnie dodaj metody area.circle() (pi razy kwadrat promienia) w pliku Circle.R oraz area.rectangle() (szerokość razy wysokość) w pliku Rectangle.R. Konstruktory są podane.
Dostarczony kod odczytuje wiersze circle 2 lub rectangle 3 4 i wypisuje klasę każdego kształtu oraz jego pole z dokładnością do dwóch miejsc po przecinku: circle: 12.57.
Twój kod umieść w plikach Shape.R, Circle.R i Rectangle.R. Plik main.R zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
source("Shape.R")
source("Circle.R")
source("Rectangle.R")
# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, " ")[[1]]
s <- if (p[1] == "circle") new_circle(as.numeric(p[2])) else new_rectangle(as.numeric(p[2]), as.numeric(p[3]))
cat(sprintf("%s: %.2f", class(s), area(s)), "\n", sep = "")
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy S3
Praca z plikamiListy z klasąFunkcje konstruktoraMetody print i formatWalidatory i funkcje pomocniczePowtórzenie — temperatury4Enkapsulacja w R
Domknięcia jako obiektyŚrodowiska jako obiektyFunkcje dostępoweOchrona stanuPodsumowanie – parkometr2Generics i metody S3
Generics i UseMethodMetody domyślneMetody dla podstawowych genericsPodstawy NextMethodPowtórzenie — pola figur5Klasy S4
Definiowanie klas S4Sloty i dostępSprawdzanie poprawnościMetody wyświetlaniaPodsumowanie – katalog produktów8Klasy referencyjne
Definiowanie klas referencyjnychMetody i aktualizacja pólSemantyka kopiowaniaDziedziczenie i callSuperPodsumowanie – kolejka zadań11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książek3Dziedziczenie S3
Wektory klasKolejność wyszukiwania metodRozszerzanie za pomocą NextMethodSprawdzanie za pomocą inherits()Powtórzenie — lista płac pracownikówPoćwicz samodzielnie: Kompilator R online