Zanim przeczytałem ten artykuł , pomyślałem, że kontrola dostępu w Rubim działa tak:
public
- może być dostępny przez dowolny obiekt (np.Obj.new.public_method
)protected
- można uzyskać dostęp tylko z samego obiektu, a także z dowolnych podklasprivate
- to samo, co chronione, ale metoda nie istnieje w podklasach
Jednak wydaje się, że protected
i private
zachowujesz się tak samo, z wyjątkiem faktu, że nie możesz wywoływać private
metod z jawnym odbiornikiem (tj. self.protected_method
Działa, ale self.private_method
nie działa).
Jaki to ma sens? Kiedy istnieje scenariusz, w którym nie chcesz, aby Twoja metoda była wywoływana z jawnym odbiornikiem?
ruby
language-design
access-specifier
Kyle Slattery
źródło
źródło
Object
mogły wywoływać prywatne metody każdego innego wystąpieniaObject
, można by było powiedzieć takie rzeczy jak5.puts("hello world")
.Odpowiedzi:
protected
metody mogą być wywoływane przez dowolną instancję klasy definiującej lub jej podklas.private
metody mogą być wywoływane tylko z poziomu obiektu wywołującego. Nie możesz uzyskać bezpośredniego dostępu do metod prywatnych innej instancji.Oto szybki praktyczny przykład:
some_method
nie możeprivate
tu być . Musi tak być,protected
ponieważ potrzebujesz go do obsługi jawnych odbiorników. Twoje typowe wewnętrzne metody pomocnicze mogą być zwykle takie,private
ponieważ nigdy nie trzeba ich tak nazywać.Należy zauważyć, że różni się to od sposobu działania Java lub C ++.
private
w Rubim działa podobnie jakprotected
w Javie / C ++, ponieważ podklasy mają dostęp do metody. W Rubim nie ma sposobu na ograniczenie dostępu do metody z jej podklas, tak jakprivate
w Javie.Widoczność w Rubim i tak jest w dużej mierze „zaleceniem”, ponieważ zawsze możesz uzyskać dostęp do metody za pomocą
send
:źródło
private
vsprotected
musiał zrobić czy podklasą mógł odziedziczyć metody, ale w rzeczywistości o tym, gdzie metoda może być wywoływana z. Dzięki!send
?Różnica
self
. Nawet ty nie możesz zadzwonićself.some_private_method
; musisz zadzwonićprivate_method
zself
domniemaniem.self
odbiornik może być jawne,self.some_private_method
jest dozwolone. (Każdy inny jawny odbiornik jest nadal niedozwolony, nawet jeśli wartość środowiska wykonawczego jest taka sama jakself
).W Rubim te rozróżnienia są po prostu radami jednego programisty dla drugiego. Metody niepubliczne to sposób na powiedzenie: „Zastrzegam sobie prawo do zmiany tego; nie polegaj na tym”. Ale nadal masz ostre nożyczki
send
i możesz przywołać dowolną metodę.Krótki poradnik
Następnie możesz biegać
ruby dwarf.rb
i zrobić to:źródło
age=
, możesz (i musisz) wywołać ją za pomocą,self
aby oddzielić ją od zmiennych lokalnych.gimli.greet
,gimli
nie dzwoniący, ale odbiorca. Obiekt wywołujący to „środowisko wykonawcze najwyższego poziomu”, które w rzeczywistości jest instancją ad-hocObject
. Spróbuj tego:ruby -e 'p self; p self.class'
Metody prywatne w Rubim:
Jeśli metoda jest prywatna w Rubim, to nie może być wywołana przez jawnego odbiorcę (obiekt). Można to wywołać tylko niejawnie. Może być wywoływana niejawnie przez klasę, w której została opisana, jak również przez jej podklasy.
Poniższe przykłady zilustrują to lepiej:
1) Klasa Animal z prywatną metodą nazwa_klasy
W tym przypadku:
2) Podklasa zwierząt zwanych płazami:
W tym przypadku:
Jak widać, metody prywatne można wywołać tylko niejawnie. Nie mogą być wywoływane przez jawnych odbiorców. Z tego samego powodu metody prywatne nie mogą być wywoływane poza hierarchią klasy definiującej.
Metody chronione w Rubim:
Jeśli metoda jest chroniona w Rubim, to może zostać wywołana niejawnie zarówno przez klasę definiującą, jak i jej podklasy. Dodatkowo mogą być wywoływane przez jawnego odbiorcę, o ile odbiorca jest sobą lub jest tej samej klasy co ja:
1) Klasa Animal z chronioną metodą protect_me
W tym przypadku:
2) Klasa ssaków dziedziczona z klasy zwierząt
W tym przypadku
3) Klasa płazów dziedziczona z klasy zwierząt (taka sama jak klasa ssaków)
W tym przypadku
4) Klasa o nazwie Drzewo
W tym przypadku:
źródło
Rozważ prywatną metodę w Javie. Można go oczywiście wywołać z poziomu tej samej klasy, ale może też zostać wywołany przez inną instancję tej samej klasy:
Tak więc - jeśli wywołujący jest inną instancją tej samej klasy - moja metoda prywatna jest faktycznie dostępna z „zewnątrz”, że tak powiem. To faktycznie sprawia, że nie wydaje się to aż tak prywatne.
Z drugiej strony, w Rubim metoda prywatna ma być prywatna tylko dla bieżącej instancji. To właśnie zapewnia usunięcie opcji jawnego odbiornika.
Z drugiej strony, z pewnością powinienem zauważyć, że w społeczności Ruby dość często nie używa się tych kontrolek widoczności, biorąc pod uwagę, że Ruby i tak daje ci sposoby na obejście ich. W przeciwieństwie do świata Java, istnieje tendencja, aby wszystko było dostępne i ufać innym programistom, że nie schrzanią sprawy.
źródło
Jednym z powodów, dla których prywatne metody mogą być dostępne przez podklasy w Rubim, jest to, że dziedziczenie Rubiego z klasami jest cienką powłoką cukrową nad zawartością modułu - w Rubim klasa jest w rzeczywistości rodzajem modułu, który zapewnia dziedziczenie itp.
http://ruby-doc.org/core-2.0.0/Class.html
Oznacza to, że w zasadzie podklasa „zawiera” klasę nadrzędną, tak że efektywnie funkcje klasy nadrzędnej, w tym funkcje prywatne , są również zdefiniowane w podklasie.
W innych językach programowania wywołanie metody obejmuje propagowanie nazwy metody w górę hierarchii klas nadrzędnych i znalezienie pierwszej klasy nadrzędnej, która odpowiada na metodę. W przeciwieństwie do tego, w Rubim, podczas gdy hierarchia klas nadrzędnych nadal istnieje, metody klasy nadrzędnej są bezpośrednio włączane do listy metod zdefiniowanej przez podklasę.
źródło
Porównanie kontroli dostępu Javy z Rubim: Jeśli metoda jest zadeklarowana jako prywatna w Javie, można uzyskać do niej dostęp tylko za pomocą innych metod w tej samej klasie. Jeśli metoda jest zadeklarowana jako chroniona, można uzyskać do niej dostęp z innych klas, które istnieją w tym samym pakiecie, jak również przez podklasy klasy w innym pakiecie. Gdy metoda jest publiczna, jest widoczna dla wszystkich. W Javie koncepcja widoczności kontroli dostępu zależy od tego, gdzie te klasy znajdują się w hierarchii dziedziczenia / pakietu.
Podczas gdy w Rubim hierarchia dziedziczenia lub pakiet / moduł nie pasują. Wszystko zależy od tego, który obiekt jest odbiorcą metody.
W przypadku metody prywatnej w Rubim nigdy nie można jej wywołać z jawnym odbiornikiem. Możemy (tylko) wywołać metodę prywatną z niejawnym odbiornikiem.
Oznacza to również, że możemy wywołać metodę prywatną z klasy, w której jest zadeklarowana, jak również ze wszystkich podklas tej klasy.
Nigdy nie można wywołać metody prywatnej spoza hierarchii klas, w której została zdefiniowana.
Metoda chroniona może zostać wywołana z niejawnym odbiornikiem, tak jak private. Dodatkowo metoda chroniona może być również wywołana przez jawnego odbiorcę (tylko), jeśli odbiorcą jest „self” lub „obiekt tej samej klasy”.
Podsumowanie
Publiczne: metody publiczne są maksymalnie widoczne
Protected: Metoda chroniona może być wywołana z niejawnym odbiornikiem, tak jak private. Dodatkowo metoda chroniona może być również wywołana przez jawnego odbiorcę (tylko), jeśli odbiorcą jest „self” lub „obiekt tej samej klasy”.
Prywatna: W przypadku metody prywatnej w Rubim nigdy nie można jej wywołać z jawnym odbiornikiem. Możemy (tylko) wywołać metodę prywatną z niejawnym odbiornikiem. Oznacza to również, że możemy wywołać metodę prywatną z klasy, w której jest zadeklarowana, jak również ze wszystkich podklas tej klasy.
źródło
źródło