Tworzenie funkcji generycznych
Część sekcji Programowanie obiektowe ścieżki R w Coddy. Lekcja 27 z 57.
Funkcję ogólną S4 tworzy się za pomocą setGeneric(). Jej ciało funkcji to standardGeneric("name"), odpowiednik S4 funkcji UseMethod(). setGeneric() zwraca nazwę funkcji ogólnej, która jest wyświetlana, gdy zostanie ona wywołana na najwyższym poziomie:
setGeneric("area", function(shape) standardGeneric("area"))Wynik:
[1] "area"Umieść wywołanie w invisible(), aby ten wiersz nie pojawił się w wynikach. setMethod("area", "Circle", ...) dodaje następnie metodę dla jednej klasy:
setClass("Circle", slots = c(r = "numeric"))
setClass("Square", slots = c(side = "numeric"))
invisible(setGeneric("area", function(shape) standardGeneric("area")))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
setMethod("area", "Square", function(shape) shape@side^2)
cat(area(new("Circle", r = 1)), area(new("Square", side = 3)))Wynik:
3.141593 9Metoda ma te same argumenty co jej funkcja generyczna. Gdy funkcja generyczna ma ..., metoda może dodać po nich własne nazwane argumenty:
setClass("Circle", slots = c(r = "numeric"))
invisible(setGeneric("describe", function(x, ...) standardGeneric("describe")))
setMethod("describe", "Circle", function(x, ..., digits = 2) {
paste("circle of area", round(pi * x@r^2, digits))
})
c1 <- new("Circle", r = 2)
print(describe(c1))
print(describe(c1, digits = 4))Wynik:
[1] "circle of area 12.57"
[1] "circle of area 12.5664"setMethod() wymaga, aby metoda ogólna już istniała, dlatego plik zawierający setGeneric() jest wczytywany jako pierwszy. Wywołanie dla klasy bez metody kończy się błędem, który podaje sygnaturę:
invisible(setGeneric("area", function(shape) standardGeneric("area")))
setClass("Circle", slots = c(r = "numeric"))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
area(42)Wynik:
Error: unable to find an inherited method for function ‘area’ for signature ‘shape = "numeric"’
Execution haltedWyzwanie
ŁatwyFigury są klasami S4 w trzech plikach. W pliku Shape.R utwórz metody generyczne area(shape) i perimeter(shape) za pomocą setGeneric(), opakowane w invisible(). W plikach Circle.R i Square.R zadeklarowano klasy; dodaj dla każdej z nich metody area i perimeter za pomocą setMethod().
Dostarczony kod odczytuje wiersze circle 2 lub square 3 i wyświetla circle: area 12.57, perimeter 12.57.
Twój kod umieść w plikach Shape.R, Circle.R i Square.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("Square.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", r = as.numeric(p[2])) else new("Square", side = as.numeric(p[2]))
cat(sprintf("%s: area %.2f, perimeter %.2f", p[1], area(s), perimeter(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ów6S4: Funkcje generyczne i metody
Tworzenie funkcji generycznychMetody dla typów wbudowanychWybór metody na podstawie dwóch argumentówsetValidity i validObjectPodsumowanie — pieniądze i walutaPoćwicz samodzielnie: Kompilator R online