29

这可能根本不是一个悖论,但从新手的角度来看,确实是这样。

> Class.superclass
=> Module
> Class.superclass.class
=> Class
> Class.superclass.class.superclass
=> Module

那么一个类的父类是模块,但模块是一个类?

我怎样才能理解这一点?

4

2 回答 2

78

TL;DR:模块是类的超类。模块是类的一个实例


让我试着更清楚地解释它。请原谅我的手写绘图 - 我没有任何精美的绘图软件。

Ruby 中的每个类都有 1 个超类*。

在此处输入图像描述

*BasicObject 除外,它没有超类。

像这样阅读上图:Float 的超类是 Numeric。Numeric 的超类是 Object 等...

当您实例化一个对象时,该对象将是某个类的一个实例。例如,“Nathan”是 String 类的一个实例。“乔”或“约翰”也是如此。1 是 Fixnum 类的一个实例,2、3、4 等也是如此……

在此处输入图像描述

像这样阅读上图:“Joe”是 String 的一个实例。1 是 Fixnum 的一个实例,等等……

嗯,在 Ruby 中,与大多数其他语言不同,Class 只是另一个类,它也可以被实例化,就像 Fixnum 或 String 一样。

在此处输入图像描述

像这样阅读上图:0.01 是 Fl​​oat 的一个实例。字符串是类的一个实例,等等......

意识到 Fixnum 是 Class 的一个实例,就像“Nathan”是 String 的一个实例一样。就像 "John" 是 String 的一个实例,Float 只是 Class 的一个实例。每个类都只是类的一个实例,甚至是类本身!

每当您在应用程序中编写一个新类时,您只是在实例化一个类为 Class 的新对象,就像 Hash.new 实例化一个新 Hash,或者“Nathan”实例化一个新 String 一样。

# By running this, you will be instantiating a new Class, and 
# it will be named Post 
class Post < ActiveRecord::Base
end

# Here is another perfectly valid way to write the above code:
Post = Class.new(ActiveRecord::Base)

# you can even instantiate a Class without giving it an explicit name:
x = Class.new(ActiveRecord::Base)

# and since your new things are classes, they can be instantiated
obj1 = Post.new
obj2 = x.new

此外,Module 只是 Class 的另一个实例。每当您在应用程序中编写新模块时,您只是在实例化一个新模块。

# this will instantiate a new Module, and assign it to Foo
module Foo
end

# Here is another perfectly valid way to write the above code:
Foo = Module.new

# you can even instantiate a Module without giving it an explicit name.
m = Module.new

顺便说一句:模块只是方法和常量的集合。类也是方法和常量的集合,但具有能够被实例化的附加功能。无法实例化模块。也就是说,m.new不会工作。

所以,回到上图,你的问题可以直接回答:

那么一个类的父类是模块,但模块是一个类?

从上图可以看出:Module 是Class的超类。

从下图中:模块是类的一个实例

于 2012-05-12T03:57:05.883 回答
15

在您的第二个示例 Class.superclass.class 中,您调用的是 Module.class。Module是指一个类,Module类。

AnyClass.superclass.class将返回 Class,除了BasicObject.superclass.class

类和实例之间的区别很重要。BasicObject 是一个类。它是一个扩展 nil 的类,这是一种说它没有超类的奇特方式。它是树的根。一切都是对象,这是说一切都是某个类的实例的另一种说法。

字符串示例

"Nathan" is an object.
"Nathan" is an instance of the String class.
"Nathan" is not a class.
"Nathan" has no superclass, because "Nathan" is not a class.

String is an object.
String is an instance of the Class class.
String's superclass is Object.

Object is an object.
Object is an instance of the Class class.
Object's superclass is BasicObject.

BasicObject is an object.
BasicObject is an instance of the Class class
BasicObject's superclass is nil.

nil is an object.
nil is an instance of the NilClass class
nil has no superclass, because it is not a class.

固定编号示例

1 is an object.
1 is an instance of the Fixnum class.
1 is not a class.
1 has no superclass, because it is not a class.

Fixnum is an object.
Fixnum is an instance of the Class class.
Fixnum's superclass is Integer.

Integer is an object.
Integer is an instance of the Class class
Integer's superclass is Numeric.

Numeric is an object.
Numeric is an instance of the Class class.
Numeric's superclass is Object.

# everything below here is in the above example.
Object is an object.
Object is an instance of the Class class.
Object's superclass is BasicObject.

BasicObject is an object.
BasicObject is an instance of the Class class
BasicObject's superclass is nil.

nil is an object.
nil is an instance of the NilClass class
nil has no superclass, because it is not a class.

所以,最后:

Class is an object.
Class is an instance of the Class class. # this is probably the most important part.
Class's superclass is Module # 2nd most important part

Module is an object
Module is an instance of the Class class. # 3rd
Module's superclass is Object # 4th

# everything below here is in the above examples.
Object is an object.
Object is an instance of the Class class.
Object's superclass is BasicObject.

BasicObject is an object.
BasicObject is an instance of the Class class
BasicObject's superclass is nil.

nil is an object.
nil is an instance of the NilClass class
nil has no superclass, because it is not a class.

表格形式:

在此处输入图像描述

如果你想验证这一切都是真的,你可以在 Ruby 中运行它

"Nathan".is_a?(BasicObject) # => true    "Nathan" is an object.
"Nathan".class #=> String                "Nathan" is an instance of the String class.
"Nathan".is_a?(Class) #=> false          "Nathan" is not a class.
"Nathan".superclass # NoMethodError      "Nathan" has no superclass, because "Nathan" is not a class.

String.is_a?(BasicObject) #=> true       String is an object.
String.class #=> Class                   String is an instance of the Class class.
String.superclass #=> Object             String's superclass is Object.

Object.is_a?(BasicObject) #=> true       Object is an object.
Object.class #=> Class                   Object is an instance of the Class class.
Object.superclass #=> BasicObject        Object's superclass is BasicObject.

BasicObject.is_a?(BasicObject) #=> true  BasicObject is an object.
BasicObject.class #=> Class              BasicObject is an instance of the Class class
BasicObject.superclass #=> nil           BasicObject's superclass is nil.

nil.is_a?(BasicObject) #=> true          nil is an object.
nil.class #=> NilClass                   nil is an instance of the NilClass class
nil.superclass # NoMethodError           nil has no superclass, because it is not a class.

从类开始:

Class.is_a?(BasicObject) #=> true        Class is an object.
Class.class #=> Class                    Class is an instance of the Class class. # this is probably the most important part.
Class.superclass #=> Module              Class's superclass is Module # 2nd most important part

Module.is_a?(BasicObject) #=> true       Module is an object
Module.class #=> Class                   Module is an instance of the Class class. # 3rd
Module.superclass #=> Object             Module's superclass is Object # 4th

Object.is_a?(BasicObject) #=> true       Object is an object.
Object.class #=> Class                   Object is an instance of the Class class.
Object.superclass #=> BasicObject        Object's superclass is BasicObject.

BasicObject.is_a?(BasicObject) #=> true  BasicObject is an object.
BasicObject.class #=> Class              BasicObject is an instance of the Class class
BasicObject.superclass #=> nil           BasicObject's superclass is nil.

nil.is_a?(BasicObject) #=> true          nil is an object.
nil.class #=> NilClass                   nil is an instance of the NilClass class
nil.superclass # NoMethodError           nil has no superclass, because it is not a class.
于 2012-05-11T21:17:15.277 回答