self 指的是当前对象。在调用方法时,分为两个步骤,查找方法和执行方法,调用方法的对象成为接收者,也就是当前对象。没有哪个对象可以一直充当当前对象的角色,并且,任何时刻,只有一个对象充当当前对象。
一. self 的含义
1。在class关键字(类)内部,self指的是类本身。1
2
3
4class Myclass
puts self
end
# Myclass
2。def 定义的方法内部,self指的是调用这个方法的对象(当前对象)1
2
3
4
5
6
7class Myclass
def my_method
pust self
end
end
$ obj = Myclass.new #=> #<Myclass:0x007f90ee0e1830>
$ obj.method #=> #<Myclass:0x007f90ee0e1830>
3。 self写在def关键字的后面,self指的是类本身1
2
3
4
5
6
7
8
9
10class Myclass
def self.my_method
puts self
end
end
$ obj = Myclass.new #=> #<Myclass:0x007fe83294de88>
$ obj.my_method #=> NoMethodError: undefined method `my_method' for #<Myclass:0x007fe83294de88>
$ Myclass.my_method #=> Myclass
由此可见,当self出现在def关键字后面时,self指的是Myclass这个类,而非Myclass类的实例obj。
二. 显式self与隐式self
《ruby元编程》中提到私有规则:私有方法只能通过阴性的接收者调用。另:当一个对象被创建时,那么它就获得了它所属类中的实例方法。
1。 ruby中定义的方法不特殊说明时,默认为public方法。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24class A
public #可省略
def method1
puts "I am method1"
self.method2
end
def method2
puts "I am method2"
end
def method3
puts "I am method3"
method2
end
end
$ obj = A.new
$ obj.method1
#=> I am method1
#=> I am method2
$ obj.method3
#=> I am method3
#=> I am method2
2。 private 定义私有方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27class A
public #可省略
def method1
puts "I am method1"
self.method3
end
def method2
puts "I am method2"
method3
end
private
def method3
puts "I am method3"
end
end
$ obj = A.new
$ obj.method3 #=> private method `method3' called for #<A:0x007fc1c9111f60> (NoMethodError)
$ obj.method1 #=> private method `method3' called for #<A:0x007f8f9e822230> (NoMethodError)
$ obj.method2
#=> I am method2
#=> I am method3
由此得知,调用私有方法时不能明确指定接收者是谁,也就是只有隐性的接受者才能调用私有方法。
三. 方法访问级别
1。private 与 protected1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53class Father
def method_a
puts "I am METHOD A in #{self.class}"
end
def method_b
puts "I am METHOD B in #{self.class}"
self.method_c #self 可以省略
end
protected
def method_c
puts "I am METHOD C in #{self.class}"
end
private
def method_secret
puts "I am method_secret in #{self.class}"
end
end
class Son < Father
def son_method_c
method_c
end
def son_method_d
self.method_c
end
def son_method_secret
self.method_secret
end
end
$ son = Son.new
$ son.son_method_c #=> I am METHOD C in Son
$ son.son_method_d #=> I am METHOD C in Son
$ son.son_method_b
#=> I am METHOD B in Father
#=> I am METHOD C in Father
$ son.method_c #=> NoMethodError: protected method `method_c' called for
$ son.method_secret #=> NoMethodError: private method `method_secret' called for
$ son.son_method_secret #=> NoMethodError: private method `method_secret' called for
$ father = Father.new
$ father.method_c #=> NoMethodError: protected method `method_c' called for
由此得知:
(1)在调用protected和private级别的方法时,不管是同类的对象(father)还是子类的对象(son),都不能够对其直接调用;只能通过其他方式,比如在别的方法中引用。
(2)ruby中的私有方法只能被阴性self调用;public方法和protected方法可被显示self和隐式self调用。