Właśnie zacząłem grać z JRuby. To jest mój pierwszy rubinowy post. Trudno mi było zrozumieć klasy i obiekty w Ruby. Nie oznacza to, jakie klasy i obiekty są w innych językach zorientowanych na obiekt. dla przykładu
Class.is_a? Object
zwraca prawdziwe i
Object.is_a? Object
zbyt.
więc klasa i obiekt są obiektami
nadchodzi kolejna
Class.is_a? Class
zwraca prawdziwe i
Object.is_a? Class
zbyt.
czekaj, jeszcze nie skończyłem
Object.instance_of? Class
Class.instance_of? Class
Obie są prawdziwe
Object.instance_of? Object
Class.instance_of? Object
Oba są fałszywe. prawo, nic nie może być instancją obiektu.
I
Class.kind_of? Class
Object.kind_of? Class
oba są prawdziwe
Class.kind_of? Object
Object.kind_of? Object
oba są prawdziwe
Więc oba są dokładnie takie same, więc dlaczego mamy oba te.
Po dalszych kopaniach napisałem tę prostą metodę, aby zwrócić listę metod obsługiwaną przez obie
irb(main):054:0> def print_methods(obj)
irb(main):055:1> obj.methods.each do |mm|
irb(main):056:2* puts mm
irb(main):057:2> end
irb(main):058:1> end
Jest tylko różnica metod między print_methods (Object) i print_methods (Class)
Nesting
jeśli zagnieżdżanie oznacza dziedziczenie, czy obiekt jest podobny do klasy zapieczętowanej?
Czy ktoś może mi wyjaśnić, co to wszystko jest?
Aktualizacja: Do komentarza Eddsa
Co ciekawe, widzę wiele różnic w liście metod w
c=Class.new
print_methods(c)
&
o=Object.new
print_methods(o)
Teraz rozumiem, że wystąpienie klasy jest naprawdę instancją klasy (a ta instancja klasy jest w rzeczywistości obiektem), a nie instancją obiektu. I nawet ta instancja pozwala mi obejść inne przypadki
xx = c.new //works - c is an Object / and xx is a instance of an Object c
yy = o.new //nope - o is already a instance of an Object, so it cannot be instantiated again
W końcu obiekt jest naprawdę instancją klasy. Bo
xx.is_a? Class
jest fałszywe, ale
xx.is_a? Object
zwraca true
Czy mam rację, ??
Odpowiedzi:
36 dla odpowiedzi nr 1Zasadniczo kluczową rzeczą do zrozumienia jest to, że każda klasa jest instancją Class
klasa i każda klasa jest podklasą Object
(w 1.8 - w 1.9 każda klasa jest podklasą BasicObject
). Tak więc każda klasa jest obiektem w tym sensie, że jest instancją podklasy Object
, tj. Class
.
Oczywiście to znaczy Class
jest instancją samą w sobie. Jeśli to cię boli, po prostu nie myśl o tym zbyt głęboko.
Object
i Class
są is_a? Object
x.is_a? y
zwraca true
gdyby x.class == y or x.class < y
, tj. jeśli x
„klasa jest y
lub x
„klasa dziedziczy z y
. Ponieważ każda klasa dziedziczy po obiekcie x.is_a? Object
zwraca prawdziwe bez względu na wszystko x
jest. (Tak czy inaczej w 1.8, w 1.9 jest też BasicObject
która jest teraz najbardziej podstawową klasą w hierarchii dziedziczenia).
Są też is_a? Class
Obie Object
i Class
są rzeczywiście klasami, więc nie powinno to dziwić.
Są też instance_of? Class
, ale nie instance_of? Object
.
w odróżnieniu is_a?
, x.instance_of? y
zwraca tylko prawda, jeśli x.class == y
, nie, jeśli x.class
jest podklasą y
. Więc od obu x
i y
są instance_of? Class
, oni nie są instance_of? Object
.
prawo, nic nie może być instancją obiektu.
To nieprawda. Object.new.instance_of? Object
jest prawdziwy.
rodzaj?
kind_of?
to alias dla is_a?
, więc patrz wyżej.
Więc oba są dokładnie takie same, więc dlaczego mamy oba te.
Należy podkreślić, że wszystko, co do tej pory jest prawdą, dotyczy wszystkich klas. Na przykład. String.is_a? Object
, String.is_a? Class
i String.instance_of? Class
są prawdziwe i String.instance_of? Object
jest fałszywy z tych samych powodów, co powyżej. (Również String.is_a? String
i String.instance_of? String
oba są fałszywe z tych samych powodów - łańcuch jest klasą, a nie łańcuchem.
Nie można z tego wywnioskować, że wszystkie klasy są takie same. One są tylko wszystkimi instancjami tej samej klasy.
Porównywanie metod
Od kiedy oboje Object
i Class
są klasami, obie mają wszystkie metody instancji zdefiniowane przez Class
. Class
dodatkowo ma metodę singleton nesting
. nesting
informuje, który moduł jest aktualnie zagnieżdżony, nie ma to nic wspólnego z dziedziczeniem.
Dla dowolnej klasy TheClass.methods
zwróci metody instancji zdefiniowane przez Class
(na przykład. superclass
, która zwraca klasę, która TheClass
dziedziczy po i new
który tworzy nowe wystąpienie TheClass
) plus metody singleton zdefiniowane przez tę klasę.
Tak czy inaczej methods
informuje tylko, które metody można wywołać bezpośrednio na danym obiekcie. Nie mówi ci, które metody można wywołać na instancji klasy. Do tego możesz użyć instance_methods
, dla którego zwracane są znacznie różne wyniki Object
i Class
.
17 dla odpowiedzi nr 2
W Rubim wszystko jest Object
w tym klasy i moduły. Object
jest najbardziej niskopoziomową klasą (cóż, w Ruby 1.9.2 jest też BasicObject
ale to inna historia).
Zobacz następujące dane wyjściowe.
> Object.ancestors
# => [Object, Kernel, BasicObject]
> Class.ancestors
# => [Class, Module, Object, Kernel, BasicObject]
> Module.ancestors
# => [Module, Object, Kernel, BasicObject]
> String.ancestors
# => [String, Comparable, Object, Kernel, BasicObject]
Jak widać, oba Class
i Module
dziedziczy z Object
.
Wracając do waszych oryginalnych twierdzeń, musicie zrozumieć różnicę między nimi
is_a?
kind_of"
instance_of?
Nie są zamienne. is_a?
i kind_of?
zwraca true, jeśli inna jest tą samą klasą lub przodkiem. Odwrotnie, instance_of?
zwraca true tylko wtedy, gdy inne są tej samej klasy.
> Class.is_a? Object
# => true
> Class.kind_of? Object
# => true
> Class.instance_of? Object
# => false
2 dla odpowiedzi nr 3
Ramesh, rubinem wszystko jest obiektem, a klasa nie jest wyjątkiem.
spróbuj tego w irb
ruby-1.9.2-p136 :001 > o = Object.new
=> #<Object:0x000001020114b0>
ruby-1.9.2-p136 :002 > o.is_a? Class
=> false
ruby-1.9.2-p136 :003 > o.is_a? Object
=> true
w tym przypadku utworzyłem instancję obiektu i sprawdziłem, czy jest to klasa (false) lub obiekt (true).
Klasa w rubinie to jakiś obiekt szablonuużywane do tworzenia instancji tej klasy. Przepraszam, że to nie jest zbyt jasne. Kluczową koncepcją jest to, że ruby jest czystym językiem obiektowym, w przeciwieństwie do języka Java.
2 dla odpowiedzi № 4
Hierarchia class / metaclass jest zawsze trochę zagadkowa :) Dla porównania, tutaj jest ten w Smalltalk; w Ruby konfiguracja opiera się na tych samych zasadach, z wyjątkiem tego, że nie ma Behavior
i ClassDescription
wyróżnienia, a także moduły i klasy własne, które należy wziąć pod uwagę.
Pełne wyjaśnienie modelu obiektu Smalltalk jest dostępne w Pharo według przykładu, jak na to wskazuje powiązane pytanie.
1 dla odpowiedzi nr 5
Jak pisze, w Ten artykuł
obiekty nie przechowują metod, tylko klasy mogą.
Pierwsze kilka sekcji ma kilka dobrych punktów na temat klas i obiektów
1 dla odpowiedzi № 6
Jedna z odpowiedzi wspomina o tym:
Zasadniczo kluczową rzeczą do zrozumienia jest tokażda klasa jest instancja klasy Class i każda klasa jest podklasą Object. Tak więc każda klasa jest obiektem w tym sensie, że jest instancją a podklasa obiektu, tj. klasa.
Chcę tylko powiedzieć to inaczej dla tych, którzytrochę skręca mózg. Najpierw zadaj sobie pytanie: co to jest instancja w programowaniu? A co to jest podklasa w programowaniu? Instancja jest po prostu zrealizowaną odmianą planu (klasy). Podklasa to po prostu klasa (plan) dziedzicząca z innej klasy (plan). Więc kiedy tworzysz nową klasę:
class Apple
end
Apple jest instancją klasy, czyli jestzrealizowane wariacje planu. Przyjmuje plan i wypełnia szczegóły (metody i zmienne) własną odmianą. Cóż, plan dziedziczy z innego planu, jakim jest Object. Zatem każda klasa jest instancją klasy, która jest podklasą obiektu.
class A
end
A.parent
=> Object
A.class
=> Class
Uwaga Klasa ma moduł w swoim łańcuchu dziedziczenia (moduł zawarty w klasie jako miks, być może ponieważ rodzic klasy jest obiektem?).
A.is_a?(Module)
=> true
Instancje (A.nowy) klasy A będzie miał własne zrealizowane wariacje A. Ale są to instancje obiektów. Musimy więc odróżnić instancje klas (np. Koniec klasy A) i instancje obiektów (a = A. nowe). Instancje obiektów mają inny łańcuch dziedziczenia. Są to zrealizowane warianty planu instancji klasy, a nie wariacja klasy klasy.
Oznacza to, że w ich łańcuchu dziedziczenia nie maKlasa lub moduł. Ale raczej inne instancje obiektów, więc jeśli A ma instancje obiektów, a B ma instancje obiektów, a A dziedziczy z B, to podczas tworzenia instancji nowego obiektu A, ta instancja będzie miała instancje B w łańcuchu dziedziczenia.
Będą również dziedziczyć z Object, ponieważ wszystko w Ruby dziedziczy z Object.
a = A.new
=> #<A:0x007f966449b8d8>
a.is_a?(Class)
=> false
a.is_a?(Module)
=> false
a.is_a?(Object)
=> true
I to jest najlepszy sposób, aby to wszystko przemyśleć. Nie wchodź zbyt głęboko w swoje myślenie. Zaakceptuj to, jak to napisałem.
-1 dla odpowiedzi № 7
Pomyśl o klasach jako obiektach globalnych.