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ę ??
Author: Andrew Grimm, 2011-02-11

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 Classis_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 yinstance_of? Class, to nie są instance_of? Object.

Racja, nic nie może być instancją obiektu.

To nieprawda. To prawda.

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.

 37
Author: sepp2k,
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 
 17
Author: Simone Carletti,
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.

 2
Author: Augusto,
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 .

 2
Author: Damien Pollet,
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

 1
Author: Subtletree,
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:

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.

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ę:
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.

 1
Author: Donato,
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.

 -1
Author: aleczapka,
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