Teraz przyjrzymy się koncepcjom enkapsulacji i zmienności w S4. Po pierwsze, zauważ, że używamy metody print(), a nie S4print(), ponieważ drukujemy określone sloty z S4_rectangle. Jak widać, jeśli nie będziemy ostrożni, nadal możemy przypisać wartości bezpośrednio do elementów wewnętrznych obiektu. Ponownie, nie powinieneś tego robić. Zauważ również, że jeśli użyjemy metody S4color(), którą stworzyliśmy wcześniej, do hermetyzacji dostępu do atrybutu color, otrzymamy błąd informujący nas, że S4color <- Nie można znaleźć funkcji . To podpowiada nam, że możemy stworzyć taką funkcję i możemy:
print(S4_rectangle@a)
#> [1] 2
S4_rectnagle@a <- 1
print(S4_rectnagle@a)
#> [1] 1
print(S4color(S4_rectangle))
#> [1] “niebieski”
S4color(S4_rectangle) <- „black”
#> Błąd w S4color (S4_rectangle) <- “black”:
nie można znaleźć funkcji „S4color <-”
print(S4color(S4_rectangle))
#> [1] “blue”
Aby stworzyć funkcję, która będzie hermetyzować dostęp do atrybutu obiektu, możemy użyć funkcji setReplaceMethod(), tak jak zrobiliśmy to z funkcją setMethod() wcześniej. Zwróć uwagę, że nazwa metody, którą przekazujemy do funkcji setGeneric, to ta, która została nam zasugerowana w błędzie R, który jest nazwą gniazda, po którym następuje normalny operator przypisania w R, <-. Zwróć również uwagę, że nie ma spacji między nazwą zmiennej a symbolami dla operatora przypisania. Na koniec zwróć uwagę, że podczas przypisywania nowej wartości do gniazda color utworzyliśmy obiekt typu S4Color. Jeśli spróbujesz po prostu przypisać ciąg, tak jak to zrobiliśmy z klasą S3, pojawi się błąd informujący, że próbujesz zrobić coś, czego nie powinieneś robić. Jest to duża zaleta podczas pracy z S4, ponieważ może zapobiec popełnieniu nieoczekiwanych błędów:
setGeneric(„S4color<-„, function(self, value) {
standardGeneric(„S4color<-„)
})
#> [1] “S4color <-“
setReplaceMethod(„S4color”, „S4Rectangle”, function(self, value) {
self@color <- new(„S4Color”, color = value)
return(self)
})
#> [1] “S4color <-“
Kiedy już stworzymy taką metodę, możemy jej użyć do bezpośredniego przypisania do obiektu koloru, w sposób hermetyzowany, co jest znacznie lepsze niż bezpośrednie manipulowanie gniazdami. Jak widać, zmiana koloru jest trwała:
print(S4color(S4_rectangle))
#> [1] “blue”
S4color(S4_rectangle) <- „black”
print(S4color(S4_rectangle))
#> [1] “black”