2011-08-31 106 views
1

现在我写了多次努力来理解红宝石的对象模型后,我感到困惑:以下是我的观察。ruby​​中类的类型和超类的区别是什么?

class Bird 
    def speak 
    puts "tweet tweet" 
    end 
end 

>> Bird.class 
=> Class 
>> Class.class 
=> Class 
>> Class.superclass 
=> Module 
>> Module.class 
=> Class 
>> Module.superclass 
=> Object 
>> Object.class 
=> Class 
>> Object.superclass 
=> nil 
>> nil.class 
=> NilClass 
>> NilClass.class 
=> Class 
>> NilClass.superclass 
=> Object 
and keeps going on .... 

这是怎么回事?什么位于祖先的零点或NilClass或Object或Class? Ruby的对象模型是如何组织的。

什么是类和什么是对象?是一个类还是一个对象?对象是对象还是类?

+0

可能会很有意思:[Ruby Inheritance](http://rubylearning.com/satishtalim/ruby_inheritance.html) - 请注意1.8和1.9在树上不一致。 – 2011-08-31 22:45:23

+0

我正在使用1.8.7 MRI – pankajdoharey

+0

在Ruby 1.9+中,“对象”。超类'返回'BasicObject' – pje

回答

2

它有点棘手。在Ruby中,一切都是一个对象(取决于你的版本)。

  • 无有它自己的NilClass,因为它不允许NilClass.new,哪个对象和类允许。它是一个对象,所以你可以像nil.nil一样调用它的方法?等等。
  • 对象是最高类,一切都从Object继承,甚至NilClass类也是一个对象,它知道如何用新方法实例化对象本身。

起初真的很奇怪,但是我发现戴夫托马斯的解释颇有启发。

参见:http://www.infoq.com/presentations/metaprogramming-rubyhttp://pragprog.com/screencasts/v-dtrubyom/the-ruby-object-model-and-metaprogramming。后者是商业性的。

+0

BasicObject是以上对象在1.9+ – 2011-08-31 22:47:28

+0

取决于您的版本:) – ayckoster

2

可以断定,你的例子如下:

  1. 出现在您的示例脚本指向一个类(BirdClassModuleObjectNilClass)写成大写的每一个名字。
  2. 每个班级依次是Class类型的对象(这就是为什么X.class总是在您的示例中返回Class)。
  3. X.superclass返回基类X
  4. Object.superclass返回nil,因为它没有基类!这确实意味着基类对象是NilClass甚至nil(这是不是一个类型,而是一个实例)
  5. 所涉及类的继承图看起来像:

    Object (top-level)  Object  Object 
        |      |   | 
    Module     Bird  NilClass 
        | 
    Class 
    
+0

但在1.9.2 ...'Object.superclass => BasicObject'和'BasicObject.superclass => nil' – 2011-08-31 22:48:43

+0

这是真的,这就是为什么我写了“你可以从你的例子中得出以下结论”。 –

0

我认为你对实例(如nil)和类(如NilClass)之间的差异感到困惑。这很有道理,因为Ruby类(NilClass)也是实例。因此:一个类是一个实例。一个实例不是一个类,虽然除非它是一个类。

Here's a detailed hierarchy,它由ObjectGraph制成。

+0

但在1.9.2 ...'Object.superclass => BasicObject' – 2011-08-31 22:47:59

1

Class为一个对象返回一个类(而一个类是一个对象)。超类是(派生)类的父类。请致电Ruby Object Model

+0

最佳答案IMO。 –

5

在ruby中,类对象实际上是Class类的一个实例。 class Foo是几乎相同的Foo = Class.new

MyClass = Class.new 
instance = MyClass.new 
puts instance # => #<MyClass:0x100c14b38> 

另外,class方法是更多的设计被称为上的实例,而不是类对象。

class Foo 
end 

f = Foo.new 
puts f.class # => Foo 

调用类对象时,语义可能很奇怪。尽管superclass的工作方式与您对类对象的期望相同。

所以鉴于这一切让解释这些一个接一个:

>> Bird.class 
=> Class 

Bird类对象有一个类的Class,因为所有的类对象是Class类的实例。

>> Class.class 
=> Class 

没错甚至ClassClass一个实例。在这种情况下,它实际上是一个循环参考。

>> Class.superclass 
=> Module 

Class类实际上是从Module继承。毕竟,一个类只是一个可以实例化的模块。但是所有非实例功能都与模块非常相似。

>> Module.superclass 
=> Object 

Module继承自Object。就像红宝石里的一切,如果你回到足够远。

>> Object.class 
=> Class 

同样所有的类对象是Class实例。

>> Object.superclass 
=> nil 

所有红宝石的一切都始于Object。它是一切的基础类。因此它没有超类。

>> nil.class 
=> NilClass 

nil实际上是引擎盖下的NilClass一个实例。 NilClass定义了nil响应的方法。如果需要,您甚至可以将方法添加到NilClass。还有一个TrueClass和一个FalseClass

>> NilClass.class 
=> Class 

再次,所有类对象都是Class的实例。从Object这样没有指定明确的超任何类

>> NilClass.superclass 
=> Object 

NilClass继承。

+0

应该指出,在1.9+上有'Object.superclass => BasicObject',所以后面和上面的结果可能并不适合每个人。 – 2011-08-31 22:50:23

+0

是的,我还没有玩过1.9,说实话:(所以请纠正任何不一致的东西。但是,尽管如此,我仍然认为它是1.8.7。 –

相关问题