ClassMethod就是可以MyClass.method的类方法
InstanceMethod就是可以MyClass.new.method的实例方法
1.最正常在类里面定义的是
1
2
3
4
5
6
7
8
9
10
11
12
|
#定义
class
MyClass
def
self
.class_method
puts
"self.class_method"
end
def
instance_method
puts
"instance_method"
end
end
#调用:
MyClass.class_method
MyClass.
new
.instance_method
|
2.更常用的是带module一起玩
module可以当成是一个组件,他扩展了类继承的功能。比如我们有Computer类和TV类,两个类都有Displayer,但问题他们的父类 ElectricalAppliance 却不是都有显示器的,这个时候他们都插入这个Displayer组件,很有意义。
也就是RUBY多继承的方法
1
2
3
4
5
|
module
Mixin
def
foo
puts
'foo'
end
end
|
1
2
3
4
5
6
7
8
9
10
|
#调用,foo为类方法(3):
Class
A
end
A
.extend(Mixin)
class
A
extend Mixin
end
class
<<
A
#注意这里使用的是include
include Mixin
end
|
1
2
3
4
5
6
7
8
9
10
|
#foo做为实例方法
Class
A
end
A
.include(Mixin)
# 这种写法在1.9.3中已经被删除,include变成私有变量,什么时候变的,不详
class
A
include Mixin
end
class
<< a
#注意这个是对A实例a这个“对象”的,class << a 等价于class A
include Mixin
end
|
1
|
以上其实很容易理解,组件的插入,extend则成为类方法,include则成为实例方法。
|
因为module本身也是一个class(ruby全家都是class),所以就得到一个Module的“类”方法,而在类中include或extend不影响
1
2
3
4
5
6
7
8
|
module
Mixin
extend
self
def
foo
puts
"foo"
end
end
#有如下
Mixin.foo
|
1
|
但是
module
是没有实例的,也就是不能Mixin.
new
,所以你不能有
|
1
|
module
Mixin ; include Mixin ;
end
|
1
|
事实如果我们这么做了,就会出现:ArgumentError: cyclic include detected ,重复的include操作。显然,我们不是不能,而是不需要。
|
5.self.included(base)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
module
Mixin
def
self
.included(base)
#included是一个回调函数,当Mixin被include的时候被调用,base就是调用 w
base.extend(ClassMethods)
base.send(
:include
, InstanceMethods)
end
module
InstanceMethods
def
foo
puts
"foo"
end
end
module
ClassMethods
def
bar
puts
"bar"
end
end
end
class
MyClass
include Mixin
end
MyClass.bar
MyClass.
new
.foo
|
我们在看rails或别的代码的时候经常会看到self.included,他的作用是在别人include他的时候调用,这样就不用在class里一个一个的选择是include 还是extend了