Metody publiczne i polimorfizm

Ponieważ S4 również używa polimorfizmu parametrycznego (metody należą do funkcji, a nie klas) i już to wyjaśniliśmy już kilka razy wcześniej, w tym miejscu wskażemy tylko różnice z S3. Po pierwsze, zamiast używać funkcji USeMethod() do rejestrowania metod w R, używamy funkcji setGeneric() z nazwą metody i funkcja, która wywołuje funkcję standardGeneric() wewnątrz. Zapewni to mechanizm wysyłania obiektów S4. Aby faktycznie utworzyć metodę, zamiast korzystać z konwencji nazewnictwa, jak to robimy w S3, w rzeczywistości przekazujemy nazwę klasy i metodę do funkcji setMethod(), a także funkcję, która powinna być stosowana jako metoda. Po drugie, kolejność ma znaczenie. Jeśli wywołasz funkcję setMethod() przed wywołaniem metody setGeneric(), mechanizm wysyłania nie zadziała. Zrobiliśmy to w S3, ale tutaj musimy odwrócić kolejność. Na koniec zwróć uwagę, że dostęp do atrybutów obiektów (gniazd) uzyskujemy za pomocą symbolu @, jak wspomnieliśmy wcześniej. Dla kompletności w przykładzie, aby czytelnik mógł porównać kod dla wszystkich trzech przykładów obok siebie, pokażemy teraz, jak zaimplementować ten sam kod, który pokazaliśmy dla przypadku S3:

setGeneric(„S4area”, function(self) {

standardGeneric(„S4area”)

})

#> [1] “S4area”

setMethod(„S4area”, „S4Rectnagle”, function(self) {

return(self@a * self@b)

})

#> [1] “S4area”

S4area(S4_rectangle)

#> [1] 6

setGeneric(„S4color”, function(self) {

standardGeneric(„S4color”)

#> [1] “S4color”

setMethod(„S4color”, „S4Rectagle”, function(self) {

return(self@color@color)

})

#> [1] “S4color”

Jeśli użyjesz print() na S4_rectangle, zobaczysz, że jest to rozpoznawane jako pewny wpis, i pokaże swoje gniazda:

print*S4_rectangle)

#> Obiekt klasy „S4Rectangle”

#> Boks „a”:

#> [1] 2

#>

#> Boks „b”:

#> [1] 3

#>

#> „Kolor” boksu:

#> Obiekt klasy „S4Color”

#> „Kolor” boksu:

#> [1] “niebieski”

Jeśli chcemy zmienić to wyjście, nadpisujemy tę metodę naszą własną, tak jak to zrobiliśmy w przypadku S3. Jeśli jednak to zrobimy, będziemy mieć zdefiniowaną funkcję print() do pracy z obiektami S4 i przestanie ona działać dla obiektów z innych modeli obiektów. Zachęcamy do samodzielnego wypróbowania, zmieniając poniższy kod tak, aby używał wywołania metody print zamiast nazwy S4print. Jak widać, używamy tego samego mechanizmu nadpisywania co poprzednio, więc pominiemy jego wyjaśnienie:

setGeneric(„S4print”, function(self) {

standardGeneric(„S4print”)

})

#> [1] “S4print”

setMethod(„S4print”, „S4Rectangle”, function(self) {

print(paste (

S4color(self), „rectangle:” , self@a, „x”. self@b . „==”, S4area(self)

))

})

#> [1] “S4print”

Teraz możemy użyć metody S4print() do wyświetlenia żądanego wyniku, jak widać w następującym kodzie:

S4print(S4_rectangle)

#> [1] “niebieski prostokąt: 2 x 3 == 6”

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *