Ruby Crazy: Class vs Object?
Właśnie zacząłem grać z Jrubym. To mój pierwszy rubinowy post. Trudno mi było zrozumieć klasy vs obiekty w Rubim. Nie oznacza to, co klasy i obiekty w innych obiektowych laguages. dla przykładu
Class.is_a? Object
Zwraca true oraz
Object.is_a? Object
Too .
Więc klasa I obiekt są obiema obiektami
Nadchodzi kolejny
Class.is_a? Class
Zwraca true oraz
Object.is_a? Class
Too .
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. racja, nic nie może być instancją obiektu.
I
Class.kind_of? Class
Object.kind_of? Class
Obie są prawdziwe
Class.kind_of? Object
Object.kind_of? Object
Obie są prawdziwe
Więc oba są dokładnie takie same, to dlaczego mamy oba te.?
Po trochę więcej kopania, napisałem ten prosty sposób, aby zwrócić listę metod obsługiwanych przez oba
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
Tylko różnica metod między print_methods (Object) i print_methods (Class) wynosi
Nesting
Jeśli Zagnieżdżanie oznacza dziedziczenie, czy obiekt jest podobny do klasy sealed??
Czy ktoś może mi wyjaśnić, co to jest?Update: to Edds comment
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 instancja klasy jest naprawdę instancją klasy (a ta instancja klasy jest rzeczywiście obiektem) nie instancja obiektu. I nawet ta instancja pozwala mi rozciągać inne instancje
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 rzeczywiście instancją klasy. Ponieważ
xx.is_a? Class
Jest fałszywe, ale
xx.is_a? Object
Zwraca true
Mam rację ??7 answers
Zasadniczo kluczową rzeczą do zrozumienia jest to, że każda klasa jest instancją klasy Class
, a 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 oznacza to, że Class
jest instancją samą w sobie. Jeśli przez to boli cię mózg, nie myśl o tym zbyt głęboko.
Object
i Class
są is_a? Object
x.is_a? y
zwraca true
if x.class == y or x.class < y
, tzn. if x
'S class is y
or x
' S class inherits from y
. Ponieważ każda klasa dziedziczy z obiektu x.is_a? Object
zwraca true bez względu na to, czym jest x
. (W 1.8 tak czy inaczej, w 1.9 istnieje również BasicObject
, która jest teraz najbardziej podstawową klasą w hierarchii dziedziczenia).
Są również is_a? Class
Zarówno Object
jak i {[0] } są rzeczywiście klasami, więc nie powinno to dziwić.
Są również instance_of? Class
, ale nie instance_of? Object
.
W przeciwieństwie do is_a?
, x.instance_of? y
zwraca true tylko wtedy, gdy x.class == y
, a nie wtedy, gdy x.class
jest podklasą y
. Więc skoro oba x
i y
są instance_of? Class
, to nie są instance_of? Object
.
To nieprawda. To prawda.Racja, nic nie może być instancją obiektu.
Kind_of?
kind_of?
jest aliasem dla is_a?
, więc patrz wyżej.
Więc oba są dokładnie takie same, to dlaczego mamy oba te.?
Należy podkreślić, że wszystko do tej pory jest prawdą dla wszystkich klas. E. g. String.is_a? Object
, String.is_a? Class
i String.instance_of? Class
są prawdziwe i String.instance_of? Object
są fałszywe z tych samych powodów, co powyżej. (Również String.is_a? String
i String.instance_of? String
są fałszywe z tych samych powodów - String jest klasą, A nie łańcuchem).
Nie można wnioskować z tego, że wszystkie klasy są takie same. Są tylko instancjami tej samej klasy.
Porównywanie metod
Ponieważ zarówno Object
jak i Class
są klasami, obie mają wszystkie metody instancji zdefiniowane przez Class
. Class
dodatkowo posiada metoda Singletona nesting
. nesting
mówi, w którym module aktualnie się zagnieżdżasz, nie ma to nic wspólnego z dziedziczeniem.
Dla danej klasy TheClass.methods
zwróci metody instancji zdefiniowane przez Class
(np. superclass
, która zwraca klasę, z której TheClass
dziedziczy, oraz new
, która tworzy nową instancję TheClass
) plus metody Singletona zdefiniowane przez tę klasę.
W każdym razie methods
mówi tylko, które metody można wywołać bezpośrednio na danym obiekcie. Nie mówi ci jakie metody można wywołać na instancji klasy. W tym celu możesz użyć instance_methods
, który zwraca znacząco różne wyniki dla Object
i Class
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-08 13:33:42
W Rubim wszystko jest Object
, w tym klasy i moduły. Object
jest najbardziej niskopoziomową klasą (cóż, w Rubim 1.9.2 jest też BasicObject
, ale to inna historia).
Zobacz następujące wyjście.
> 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 widzisz, zarówno Class
jak i Module
dziedziczą z Object
.
Wracając do oryginalnych twierdzeń, musisz zrozumieć różnicę
is_a?
kind_of'
instance_of?
Nie są wymienne. is_a?
i kind_of?
zwraca true, jeśli other jest tą samą klasą lub przodkiem. Odwrotnie, instance_of?
zwraca true tylko wtedy, gdy other jest tą samą klasą.
> Class.is_a? Object
# => true
> Class.kind_of? Object
# => true
> Class.instance_of? Object
# => false
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-11 09:57:56
Ramesh, w ruby 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) czy obiekt (true).
Klasa w Rubim, jest rodzajem obiektu szablonu używanego do tworzenia instancji tej klasy. Przykro mi, że to nie jest zbyt jasne. Kluczową koncepcją jest to, że ruby jest czystym językiem zorientowanym obiektowo, w przeciwieństwie do Javy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-11 09:56:50
Hierarchia klasy / metaclass jest zawsze trochę zastanawiająca:) dla porównania, Oto ten w Smalltalku; w Rubim konfiguracja opiera się na tych samych zasadach, z tym, że nie ma rozróżnień Behavior
i ClassDescription
, A są moduły i eigenclasses do wzięcia pod uwagę.
Pełne wyjaśnienie modelu obiektowego Smalltalk jest dostępne w Pharo na przykładzie , na co wskazuje to powiązane pytanie .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:25:31
Jak pisze w Ten artykuł
Obiekty nie przechowują metod, tylko klasy mogą.
Pierwsze sekcje mają kilka dobrych punktów o klasach vs obiektach
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-23 10:42:44
Jedna z odpowiedzi mówi o tym:
Chcę tylko powiedzieć to inaczej dla tych, którzy mają mały przekręt mózgu. Najpierw zadaj sobie pytanie: Czym jest instancja w programowaniu? A co to jest podklasa w programowaniu? Na instancja jest tylko zrealizowaną odmianą schematu (klasy). Podklasa jest po prostu klasą (blueprint), która dziedziczy z innej klasy (blueprint). Więc kiedy tworzysz nową klasę:Zasadniczo kluczową rzeczą do zrozumienia jest to, że każda klasa jest instancja klasy klasa i każda klasa jest podklasą obiektu. Więc każda klasa jest obiektem w tym sensie, że jest instancją podklasa obiektu, czyli Klasa.
class Apple
end
Apple jest instancją klasy, czyli jest realizowaną odmianą schematu. Pobiera schemat i wypełnia szczegóły (metody i zmienne) własną zmiennością. Schemat dziedziczy po innym schemacie, którym jest obiekt. Więc każda klasa jest instancją klasy, który jest podklasą obiektu.
class A
end
A.parent
=> Object
A.class
=> Class
Uwaga klasa ma moduł w swoim łańcuchu dziedziczenia (moduł dołączony do klasy jako mixin może ponieważ rodzicem klasy jest obiekt?).
A.is_a?(Module)
=> true
Instancje (A. new) klasy A będą miały swoje własne zrealizowane odmiany A. ale są instancjami obiektowymi. Musimy więc rozróżnić instancje klas (np. class A end) i instancje obiektów (a = A. new). Instancje obiektów mają inny łańcuch dziedziczenia. Są one realizowaną odmianą instancji klasy / align = "left" /
Oznacza to, że ich łańcuch dziedziczenia nie jest klasą ani modułem. Ale raczej inne instancje obiektu, więc jeśli A ma instancje obiektu, A B ma instancje obiektu, a a dziedziczy z B, kiedy utworzymy nową instancję obiektu A, ta instancja będzie miała instancje B w swoim łańcuchu dziedziczenia.
Będą również dziedziczyć po obiekcie, ponieważ wszystko w Rubim dziedziczy po obiekcie.
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 o tym myśleć wszystkie. Nie wchodź zbyt głęboko w swoje myślenie. Zaakceptuj to tak, jak napisałam.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-06 15:36:47
Myśl o klasach jako o obiektach globalnych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-08 09:08:54