Ruby疯狂:Class vs Object?

时间:2011-02-11 09:45:11

标签: ruby class object

我刚开始玩JRuby。这是我的第一篇红宝石帖子。我很难理解Ruby中的类和对象。它并不意味着什么类和&其他面向对象的对象中的对象。例如

Class.is_a? Object

返回 true

Object.is_a? 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

如果嵌套意味着继承,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实际上是一个Class的实例。因为

  xx.is_a? Class 

是假的,但是

  xx.is_a? Object 

返回true

我是对的,??

7 个答案:

答案 0 :(得分:38)

基本上要理解的关键是每个类都是Class类的一个实例,每个类都是Object的子类(在1.8 - 1.9中,每个类都是{{的子类) 1}})。因此,每个类都是一个对象,因为它是BasicObject的子类的实例,即Object

当然这意味着Class是其自身的一个实例。如果这会让你的大脑受到伤害,那就不要太深思。

ClassObjectClass

is_a? Object如果x.is_a? y则返回true,即x.class == y or x.class < y的班级为xy的班级是否继承自x 1}}。由于每个类都继承自对象y,因此无论x.is_a? Object是什么,都会返回true。 (无论如何,在1.8中,还有x,它现在是继承层次结构中最基本的类。)

他们也是BasicObject

is_a? ClassObject都是类,所以这不应该令人惊讶。

它们也是Class,但不是instance_of? Class

instance_of? Object不同,is_a?仅在x.instance_of? y时返回true,而x.class == y则不是x.class的子类。因为yx都是y,所以它们不是instance_of? Class

  

对,没有什么可以是对象的实例。

那不是真的。 instance_of? Object是真的。

kind_of?

Object.new.instance_of? Objectkind_of?的别名,请参见上文。

  

所以两者完全相同,那为什么我们都有这两个。?

应该指出的是,到目前为止所有课程都适用。例如。由于与上述相同的原因,is_a?String.is_a? ObjectString.is_a? Class为真,String.instance_of? Class为假。 (同样的原因,String.instance_of? ObjectString.is_a? String都是假的 - 字符串是一个类,而不是一个字符串。)

你不能断定所有类都是一样的。它们只是同一类的所有实例。

比较方法

由于String.instance_of? StringObject都是类,因此它们都具有Class定义的所有实例方法。 Class另外还有单例方法Classnesting告诉您当前嵌套的模块,它与继承无关。

对于任何给定的类nesting将返回TheClass.methods定义的实例方法(例如Class,它返回superclass继承的类,{{1} }创建一个新的TheClass}实例加上该类定义的单例方法。

无论如何new只告诉你可以直接在给定对象上调用哪些方法。它不会告诉您可以在类的实例上调用哪些方法。为此,您可以使用TheClass,这会为methodsinstance_methods返回截然不同的结果。

答案 1 :(得分:18)

在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]

如您所见,ClassModule都来自Object

回到原来的断言,你必须了解其中的差异

  • is_a?
  • kind_of'
  • instance_of?

它们不可互换。如果other是同一个类或祖先,则is_a?kind_of?返回true。相反,instance_of?仅当other是同一个类时才返回true。

> Class.is_a? Object
# => true 
> Class.kind_of? Object
# => true 
> Class.instance_of? Object
# => false 

答案 2 :(得分:2)

Ramesh,红宝石一切是一个对象,一个类也不例外。

在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 

在这种情况下,我创建了一个Object实例,并检查它是一个类(false)还是一个Object(true)。

ruby​​中的一个类,是用于创建该类实例的某种模板对象。对不起,这不是很清楚。关键概念是ruby是一种纯粹的面向对象语言,而不是Java。

答案 3 :(得分:2)

类/元类层次结构总是有点令人费解:)只是为了比较,here's the one in Smalltalk;在Ruby中,设置基于相同的原则,除了它没有BehaviorClassDescription区别,并且有模块和特征类需要考虑。

Pharo by Example提供了对Smalltalk对象模型的完整说明,如related question所示。

答案 4 :(得分:1)

_Why写在this article

  

对象不存储方法,只有类可以。

前几节有关于类与对象的一些好处

答案 5 :(得分:1)

其中一个答案提到了这一点:

  

基本上要理解的关键是每个班级都是   Class类的实例,每个类都是Object的子类。   因此,每个类都是一个对象,因为它是一个实例   Object的子类,即Class。

我只想对那些有一点脑力扭曲的人说出不同的话。首先问问自己:编程中的实例是什么?什么是编程中的子类?实例只是蓝图(Class)的实现变体。子类只是一个继承自另一个类(蓝图)的类(蓝图)。所以当你创建一个新类时:

class Apple
end

Apple是Class的一个实例,也就是说,它是蓝图的实现变体。它采用蓝图并用自己的变体填充细节(方法和变量)。嗯,蓝图继承自另一个蓝图,即Object。所以每个类都是Class的一个实例,它是Object的子类。

class A 
end
A.parent  
=> Object     
A.class  
=> Class

注意类在其继承链中有Module(模块包含在Class中作为mixin,因为Class的父类是Object?)。

A.is_a?(Module)
 => true  

A类的实例(A.new)将有自己实现的A变体。但它们是对象实例。所以我们必须区分类实例(例如A类结束)和对象实例(a = A.new)。对象实例具有不同的继承链。它们是类实例蓝图的实现变体,而不是类Class的变体。

这意味着在他们的继承链中不是Class或Module。而是其他对象实例,因此如果A具有对象实例且B具有对象实例且A继承自B,则当我们实例化A的新对象实例时,此实例将在其继承链中具有B实例。

它们也将继承自Object,因为Ruby中的所有内容都继承自Object。

a = A.new
 => #<A:0x007f966449b8d8> 
a.is_a?(Class)
 => false 
a.is_a?(Module)
 => false 
a.is_a?(Object)
 => true 

这是考虑这一切的最佳方式。不要过于深思你的想法。正如我写的那样接受这个。

答案 6 :(得分:-1)

将Classes视为全局对象。