不好意思,这其实是之前的一篇文章,改了个标题。
之所以这样做,是因为之前写的有点混乱,事实上之前自己也没完全理清楚,所以今天做了大幅度修改,这是一个试图将 Ruby类模型
理论化的尝试,有时候心里明白一件事和将这件事清晰的讲出来, 是完全两码事,后者往往难得多。
无论你是否读过,不妨再次读一读,这次的概念,应该是清晰多了,事实上本人也经历了一个从模糊到清晰的过程,我并没有读过 C 的源码,但是这不妨碍 我猜它 ... 从 Ruby 的角度... 不对莫怪!
如果谁能指出不准确的地方,那就太感谢啦。如果大家都不感兴趣 (我承认大多数人应该不感兴趣), 权当做对自己之前的一个模糊的概念的修正吧。
类对象
只不过是 Ruby 内核中 Class类的一个实例
. 当你创建一个新类时,就会创建 Class 类的一个对象。下面的代码更清楚:
a_class = Class.new(Object)
Klass = a_class
等价于:
class Klass < Object
end
类
又是什么?这里的类,指的是 类定义
, 而非类对象。为什么一定要这样区分?后面自然见分晓。
你只要明白,这里要讲的 类
这个概念,是一个面向对象的语言 (例如 Ruby ), 面向对象消息机制的实现方式..
类定义
呢?似乎就只有以下三种对象,他们真实的属于 类定义
, 在所有情况下,你只能通过 类对象
或 类实例对象
的方式来引用这些定义的值。
1) 类的实例方法
类实例方法 是属于类自身的,这里有点名不符实,因为它是实实在在属于 类定义
方法,而不是 类实例之上定义的方法
, 只不过你只能通过 类实例对象
的方式来引用它。
2) @@类变量
它有点像是作用在整个类继承层次的 全局变量
, 它的行为像是没有命名空间的全局常量,在 一个类及其所有子类中
总是唯一的。既然他属于 类和它的子孙
公用的那一部分,那也必然应该属于类了,@@类变量是私有的,你只能在类定义内部隐式的访问它。
3) 类常量
类似于 类实例方法
, 它属于也属于类定义,但是很明显,类常量同样可以通过域作用符 类对象::常量名
(命名空间) 的方式,通过外部空间来访问它。
@@类变量 和 类常量 都只能通过 类对象
来引用它,不过他们的可见性不同,前者是 private, 后者是 public.
类实例变量,跟这里提及的 类定义
没有一点关系,他只是 类对象
的实例变量,他是 private 的,你只能在类定义内部隐式的访问它。
类实例变量
和 类常量
非常相似,他们的共通点是:
他们都可以在类方法中被直接使用。(self 都指向了类对象), 事实上在创建一个类时,两者经常互相混用。
它们的不同点是:
只不过是在类对象之上被定义的方法。跟类定义没有任何关系。(你有在类中直接使用类方法吗?) 可能发现了,又有一点名不符实。因为 类方法
, 实实在在不属于 类
, 而是属于 类对象
.
类定义
和 类对象
只有一个原因,属于类定义的部分,无论是 类方法
还是 实例方法
中都可以直接访问,你甚至可以理解为在这种情况下,会将 self 从 实例对象
反射到 类对象
.
上面这一句话,就是我总结出来的就是 Ruby 类/对象模型所有魔法的根源。
类::常量
方式访问的是 类对象
的常量
类::方法
方式访问的是 类对象
的方法。
而我们通常在 类定义
内部定义的常量
以及类方法
, 前者是真实属于类定义,而后者跟 类定义
没有一点关系,只不过他们都可以在 self (即类对象) 之上被引用而已。
还有最后给出一个有趣的实例,直接看代码:
class MyClass
CONSTANT = 100
@@class_variable = 200
@class_instance_variable = 300
def self.hello
p CONSTANT
p @@class_variable
p @class_instance_variable
end
def hello
p CONSTANT
p @@class_variable
p @class_instance_variable
end
end
MyClass.hello
puts "-" * 30
MyClass.new.hello
# 输出结果如下:
# 100
# 200
# 300
# ------------------------------
# 100
# 200
# nil
为什么会输出这样的结果呢?
你定义了一个 类常量
, 一个类变量
, 一个 类实例变量
.
前两者是属于 类定义
, 而后者是完全属于 类对象
自己的实例变量,因此,即使在 类实例方法
中你也可以访问前两者,而后者则不同,它不属于类定义,它访问的是对象自身的私有实例变量,默认初始化为 nil.
我觉得我应该讲清楚了,从最初的原本只是想写几行,说说 Ruby 中一些有趣的事儿,到后来越写越多,最后成了一个分享,中间的过程,还是蛮乱的,不过我已经很努力了。
等有空的话,我希望希望再分享其他一些跟 Ruby 有关的心得,例如:继承,混入,扩展有关的一些知识。权当作为这篇文章的姐妹篇。
为了说明 我所讲的类概念
在实际的应用中有多么的重要,试着编写了几个练习题,如果你真的看明白了我的分享 (或者你原本就明白), 你一定可以轻松解答。
一个模块中,定义了 常量
, 类变量
, 实例方法
, 类方法
, 类实例变量
, 当这个模块被混入一个类时,请问,那些数据可以被混入 ??
一个类中的那些东西,是可以被继承
的?