Funkcje konstruktora
Część sekcji Programowanie obiektowe ścieżki R w Coddy. Lekcja 3 z 57.
Ponieważ R nigdy nie sprawdza pól obiektu S3, każdy obiekt danej klasy powinien być tworzony przez jedną funkcję — jej konstruktor. Zgodnie z konwencją konstruktor niskiego poziomu nazywa się new_ plus nazwa klasy. Przyjmuje każde pole jako argument, sprawdza typy za pomocą stopifnot() i zwraca obiekt:
new_money <- function(amount = double(), currency = character()) {
stopifnot(is.double(amount), is.character(currency))
structure(list(amount = amount, currency = currency), class = "money")
}
m <- new_money(9.5, "EUR")
cat(m$amount, m$currency)Wynik:
9.5 EURstopifnot() zatrzymuje program, gdy jeden z jego warunków nie jest TRUE, a komunikat wskazuje, który test nie przeszedł. Nieprawidłowy typ jest wykrywany w chwili tworzenia obiektu, a nie później, gdy użyje go jakaś inna funkcja:
new_money <- function(amount = double(), currency = character()) {
stopifnot(is.double(amount), is.character(currency))
structure(list(amount = amount, currency = currency), class = "money")
}
m <- new_money("9.5", "EUR")Wynik:
Error in new_money("9.5", "EUR") : is.double(amount) is not TRUE
Calls: new_money -> stopifnot
Execution haltedKonstruktor to jedyne miejsce, w którym wywoływana jest funkcja structure() dla klasy, więc każdy obiekt ma te same pola w tej samej kolejności. Kod, który potrzebuje wielu obiektów, wywołuje ją w pętli lub za pomocą lapply():
new_point <- function(x = 0, y = 0) {
stopifnot(is.numeric(x), is.numeric(y))
structure(list(x = x, y = y), class = "point")
}
pts <- lapply(1:3, function(i) new_point(i, i * i))
for (p in pts) cat(p$x, p$y, "\n")Wynik:
1 1
2 4
3 9 Obiekt S3 nie musi być listą. Konstruktor może nadać etykietę zwykłemu wektorowi i przechowywać dodatkowe informacje jako atrybuty — tak działają wbudowane w R czynniki i daty. attr(x, "unit") odczytuje atrybut:
new_distance <- function(value = double(), unit = "m") {
stopifnot(is.double(value), is.character(unit))
structure(value, unit = unit, class = "distance")
}
d <- new_distance(c(1.5, 2), "km")
print(attr(d, "unit"))
print(unclass(d)[2] * 1000)Wynik:
[1] "km"
[1] 2000Wyzwanie
ŁatwyUzupełnij konstruktor new_book(title, author, pages) w pliku Book.R. Sprawdza on za pomocą stopifnot(), czy title i author są typu character, a pages typu numeric, i zwraca listę z tymi trzema polami oraz klasą book. Następnie uzupełnij book_label(b), która zwraca Dune by Frank Herbert, 412 pages.
Dostarczony kod odczytuje wiersze w formacie title;author;pages. Przekazuje pages jako liczbę, jeśli składa się z cyfr, a w przeciwnym razie jako oryginalny tekst, wyświetla book: i etykietę każdego obiektu oraz wyświetla rejected: i tytuł, gdy konstruktor zatrzyma działanie.
Umieść swój kod w pliku Book.R. Plik main.R zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
source("Book.R")
# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, ";")[[1]]
pages <- if (grepl("^[0-9]+$", p[3])) as.numeric(p[3]) else p[3]
b <- tryCatch(new_book(p[1], p[2], pages), error = function(e) NULL)
if (is.null(b)) {
cat("rejected: ", p[1], "\n", sep = "")
} else {
cat(class(b), ": ", book_label(b), "\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