/ / Ruby craziness: Class vs Object? - ruby, klasa, obiekt

Rubinowe szaleństwo: klasa kontra obiekt? - rubin, klasa, obiekt

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 1

Zasadniczo 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 Classis_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 yinstance_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.