我刚开始玩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
我是对的,??
答案 0 :(得分:38)
基本上要理解的关键是每个类都是Class
类的一个实例,每个类都是Object
的子类(在1.8 - 1.9中,每个类都是{{的子类) 1}})。因此,每个类都是一个对象,因为它是BasicObject
的子类的实例,即Object
。
当然这意味着Class
是其自身的一个实例。如果这会让你的大脑受到伤害,那就不要太深思。
Class
和Object
为Class
is_a? Object
如果x.is_a? y
则返回true
,即x.class == y or x.class < y
的班级为x
或y
的班级是否继承自x
1}}。由于每个类都继承自对象y
,因此无论x.is_a? Object
是什么,都会返回true。 (无论如何,在1.8中,还有x
,它现在是继承层次结构中最基本的类。)
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?
的别名,请参见上文。
所以两者完全相同,那为什么我们都有这两个。?
应该指出的是,到目前为止所有课程都适用。例如。由于与上述相同的原因,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
和Object
都是类,因此它们都具有Class
定义的所有实例方法。 Class
另外还有单例方法Class
。 nesting
告诉您当前嵌套的模块,它与继承无关。
对于任何给定的类nesting
将返回TheClass.methods
定义的实例方法(例如Class
,它返回superclass
继承的类,{{1} }创建一个新的TheClass
}实例加上该类定义的单例方法。
无论如何new
只告诉你可以直接在给定对象上调用哪些方法。它不会告诉您可以在类的实例上调用哪些方法。为此,您可以使用TheClass
,这会为methods
和instance_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]
如您所见,Class
和Module
都来自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中,设置基于相同的原则,除了它没有Behavior
和ClassDescription
区别,并且有模块和特征类需要考虑。
Pharo by Example提供了对Smalltalk对象模型的完整说明,如related question所示。
答案 4 :(得分:1)
答案 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视为全局对象。