> singleton class: 单例类就是打开Class实例的类就是单例类
class A
class << self
p self
def hello
p self
end
end
end
A.hello
输出结果
#<Class:A>
A
看输出结果:我们重点看第一个,其实第一个结果就是单例类,看下面代码:
class A
class << self
p self
def hello
p self
end
end
end
p A.singleton_class
看输出结果:
#<Class:A>
singleton_class这个方法就是查看类的单例类是什么,好了,到这里我么应该已经大概了解单例类了,其实就是打开Class实例(A)的作用域,开辟了一块空间,这块空间我们就称为单例类,这里还有点注意<<这个符号就是打开的意思,后面是打开的对象。
Singleton Method:一个实例独有的方法,只有一个receiver接受者
看下面代码:
class A
def self.hi
p self
p 'hi'
end
end
A.hi
输出结果:
A
"hi"
A是Class的实例,在A这个实例上定义方法,归A这个实例所有,这个方法就单列方法了。
看下面的例子:
class A
def A.hey
p 'hey'
end
end
A.hey
输出结果
hey
同上 这个的A就是self
在看下面的例子:
class A
class << self
def hello
p 'hello'
end
end
end
A.hello
输出结果:
"hello"
看到这个我们很熟悉了, 相当于在打开self实例然后声明了方法,这里就引出一个概念了。打开什么实例对象,那么下面的方法都只归属于这个实例对象,而这里的self就是A,所以下面的方法都属于A这个对象
在看下面的例子:
class A
(class << A; self; end).class_eval do
def you
p 'you'
end
end
end
A.you
看上面的代码估计会有点疑惑,这种方式在平时开发中用的还是很少的,但是在看一些gem源码的时候还是有用到的。
来分析一下:
(class << A; self; end),返回值是self,就是单例类,上面已经说过,通过打开那个实例对象开辟的单列空间,那么这里面的方法也就属于这个实例对象。
看如下代码:
class C ; end
C.singleton_class.class_eval do
def ba
p "ba"
end
end
C.ba
输出结果:
"ba"
其实是一样,C.singleton_class就是单例类,在这个里面声明的方法也都属于C,因为这个单例类环境是属于C的所有物。
总结:
单例类:其实就是个特殊的类,没一个类都有个单列类,可以通过调用singleton_class获取单例类,这个单例类是属于谁的,这个空间里面的方法就属于谁的,因为这个单例类只有这个谁才能开辟空间。
单列方法:其实就是有个receiver接受者,这个方法只有这一个receiver,那么这个方法就是单列方法,这个方法就单列方法了,其实单列类里面的方法就是单列方法,受力对象也就只有一个。