Сумасшествие Ruby: класс против объекта?
Я только начал играть с JRuby. Это мой первый рубиновый пост. Мне было трудно понять классы и объекты в Ruby. Это не значит, что классы и объекты в других объектно-ориентированных языках. для примера
Class.is_a? Object
возвращает true
и
Object.is_a? Object
слишком.
поэтому class и Object являются объектами
вот еще один
Class.is_a? Class
возвращает true
и
Object.is_a? Class
слишком.
подождите, я еще не закончил
Object.instance_of? Class
Class.instance_of? Class
Оба являются истинными
Object.instance_of? Object
Class.instance_of? Object
Оба являются ложными. правильно, ничто не может быть экземпляром объекта.
И
Class.kind_of? Class
Object.kind_of? Class
оба истины
Class.kind_of? Object
Object.kind_of? Object
оба истины
Итак, оба они точно такие же, тогда почему у нас есть оба этих.?
После некоторого дополнительного копания я написал этот простой метод для возврата списка методов, поддерживаемого обоими
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
Единственное различие методов между print_methods (Object) и print_methods (Class) -
Nesting
если Nesting означает наследование, Is Object похож на запечатанный класс?
Может кто-нибудь уточнить, что это такое?
Обновление: К комментарию Edds
Интересно, что я вижу много различий в списке методов в
c=Class.new
print_methods(c)
&
o=Object.new
print_methods(o)
Теперь я понимаю, что экземпляр класса действительно является экземпляром класса (и этот экземпляр класса фактически является объектом Object), а не экземпляром объекта. И даже этот экземпляр позволяет мне охватывать другие экземпляры
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
Итак, объект Object действительно является экземпляром класса. Поскольку
xx.is_a? Class
false, но
xx.is_a? Object
возвращает true
Am я right,??
Ответы
Ответ 1
В основном ключевое значение для понимания состоит в том, что каждый класс является экземпляром класса Class
, и каждый класс является подклассом Object
(в 1.8 - в 1.9 каждый класс является подклассом BasicObject
). Таким образом, каждый класс является объектом в том смысле, что он является экземпляром подкласса Object
, т.е. Class
.
Конечно, это означает, что Class
является экземпляром самого себя. Если это причиняет боль мозгу, просто не думайте об этом слишком глубоко.
Object
и Class
являются is_a? Object
x.is_a? y
возвращает true
, если x.class == y or x.class < y
, т.е. если класс x
class y
или x
наследуется от y
. Поскольку каждый класс наследует объект x.is_a? Object
, возвращает true независимо от того, что x
. (В 1.8 в любом случае в 1.9 там также BasicObject
, который теперь является самым основным классом в иерархии наследования).
Они также is_a? Class
Оба Object
и Class
действительно являются классами, поэтому это не должно удивлять.
Они также instance_of? Class
, но не instance_of? Object
.
В отличие от is_a?
, x.instance_of? y
возвращает true, если x.class == y
, а не если x.class
является подклассом y
. Так как оба x
и y
являются instance_of? Class
, они не instance_of? Object
.
вправо, ничего не может быть экземпляром объекта.
Это не так. Object.new.instance_of? Object
истинно.
kind_of?
kind_of?
является псевдонимом для is_a?
, поэтому см. выше.
Итак, оба они точно такие же, тогда почему у нас есть оба этих.?
Следует отметить, что все до сих пор верно для всех классов. Например. String.is_a? Object
, String.is_a? Class
и String.instance_of? Class
являются истинными, а String.instance_of? Object
является ложным по тем же причинам, что и выше. (Также String.is_a? String
и String.instance_of? String
являются ложными по тем же причинам - String - это класс, а не строка).
Вы не можете заключить из этого, что все классы одинаковы. Это всего лишь экземпляры одного и того же класса.
Сравнение методов
Поскольку оба Object
и Class
являются классами, оба они имеют все методы экземпляра, определенные Class
. Class
дополнительно имеет одноэлементный метод nesting
. nesting
сообщает вам, какой модуль вы в настоящее время вложены, он не имеет ничего общего с наследованием.
Для любого заданного класса TheClass.methods
будут возвращены методы экземпляра, определенные Class
(например, superclass
, который возвращает класс, на который наследуется TheClass
, и new
), который создает новый экземпляр TheClass
) плюс методы singleton, определенные этим классом.
В любом случае methods
указывает только, какие методы могут быть вызваны непосредственно на заданный объект. Он не говорит вам, какие методы могут быть вызваны на экземпляр класса. Для этого вы можете использовать instance_methods
, который возвращает значительно разные результаты для Object
и Class
.
Ответ 2
В Ruby все это Object
, включая классы и модули. Object
- это самый низкоуровневый класс (ну, в Ruby 1.9.2 есть также BasicObject
, но это уже другая история).
См. следующий вывод.
> 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]
Как вы можете видеть, оба Class
и Module
наследуются от Object
.
Вернемся к вашим первоначальным утверждениям, вам нужно понять разницу между ними
-
is_a?
-
kind_of'
-
instance_of?
Они не взаимозаменяемы. is_a?
и kind_of?
возвращает значение true, если другое является тем же классом или предком. И наоборот, instance_of?
возвращает true только в том случае, если другое является тем же классом.
> Class.is_a? Object
# => true
> Class.kind_of? Object
# => true
> Class.instance_of? Object
# => false
Ответ 3
Ramesh, в ruby все - это объект, а класс не является исключением.
попробуйте это в 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
в этом случае я создал экземпляр объекта и проверил, является ли он классом (false) или Object (true).
Класс в ruby - это какой-то объект шаблона, используемый для создания экземпляров этого класса. Извините, что это не очень понятно. Основная концепция заключается в том, что ruby - это чисто объектно-ориентированный язык, в отличие от Java.
Ответ 4
Иерархия класса/метакласса всегда немного озадачивает:) Просто для сравнения здесь в Smalltalk; в Ruby настройка основана на тех же принципах, за исключением того, что она не имеет различий Behavior
и ClassDescription
, и есть модули и eigenclasses, которые необходимо учитывать.
Полное объяснение объектной модели Smalltalk доступно в Pharo по примеру, как указано в этом связанный вопрос.
Ответ 5
Как _why пишет в в этой статье
объекты не хранят методы, только классы могут.
В первых парах раздела есть несколько полезных советов о классах vs objects
Ответ 6
Подумайте о Классах как глобальных объектах.