public method
1
2
3
4
5
6
7
8
9
| class Book
def name
"name"
end
end
book = Book.new
puts book.name
|
public是默认的方式,可以以实例化的方式通过.
号来进行访问, 可以被定义它的类和其子类访问,可以被类和子类的实例对象调用
private method
1
2
3
4
5
6
7
8
9
| class Book
private
def private_name
"private_name"
end
end
book = Book.new
puts book.private_name
|
1
2
3
4
5
| 13:in `<main>': private method `private_name' called for an instance of Book (NoMethodError)
puts book.private_name
^^^^^^^^^^^^^
Did you mean? private_methods
|
可以看见,在外部是无法去直接访问private method的
1
2
3
4
5
6
7
8
9
10
11
12
13
| class Book
def show_private
private_name
end
private
def private_name
"private_name"
end
end
book = Book.new
puts book.show_private
|
要想访问private method,必须在类的内部直接引用private method
,而不能在任何外部以实例的方式去引用
private和self的关系
在网上很多几乎,几乎我看到过的,全都在说private的一个特点就是只能在内部直接使用,不能通过.
来调用,甚至self
都不行,这里我要证实一下,其实这是个天大的谣言!!! 按照官方说法其实是private
是不能指定显示的receiver
,也就是不能显示指定调用者,必须要通过默认的调用者,也就是self
,所以其实通过self.private
是没有问题的, 是不是这样的直接证实一下就行
1
2
3
4
5
6
7
8
9
10
11
12
13
| class Book
def show_private
self.private_name
end
private
def private_name
"private_name"
end
end
book = Book.new
self.puts book.show_private
|
可以看出确实是正确输出了,另外,puts
也是private method
,用self.puts
也是能正确输出的,事实再次证明,一定一定不要去完全相信网上的东西,只有权威的官方文档才是唯一值得信赖的
protected
关于protected
和private
的区别是非常晦涩,感觉很不好说清楚,这里直接举几个例子来演示可能会更好的理解
1
2
3
4
5
6
7
8
9
| class Book
protected
def protect_name
"protected_name"
end
end
book = Book.new
puts book.protect_name
|
1
2
3
4
| 2.rb:19:in `<main>': protected method `protect_name' called for an instance of Book (NoMethodError)
puts book.protect_name
^^^^^^^^^^^^^
Did you mean? protected_methods
|
: 从这个层面来讲,proteced
和private
是一样的,在外部,均不能被类的实例对象直接调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| class Book
protected
def protect_name
"protected_name"
end
end
class Comic < Book
def display
Book.new.protect_name
end
end
puts Comic.new.display
|
这里新建一个Comic
类继承于Book
类,注意,这里开始就有差别了,这里Book
的子类Comic
里调用了Book
类的实例来访问这个protected
的方法,这里是没有报错的,正确输出方法结果,所以,protected
方法是可以在类和子类里的实例进行访问的,前面举的例子我刻意强调在类的外部,protected
是无法调用的,但是在内部它可以调用,这里可以再次验证下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| class Book
protected
def protect_name
"protected_name"
end
end
class Comic
def display
Book.new.protect_name
end
end
puts Comic.new.display
|
1
2
3
4
5
| 3.rb:11:in `display': protected method `protect_name' called for an instance of Book (NoMethodError)
Book.new.protect_name
^^^^^^^^^^^^^
Did you mean? protected_methods
from 3.rb:16:in `<main>'
|
这里仅仅是把Comic
类设置成独立的类,不是继承于Book
了,所以内部是会报错了,这里还可以去验证private
是否可以用内部实例去访问,就不再演示了,private
是无法跟protected
一样可以在内部通过实例去访问的
小结
经过演示验证,可以得出结果,private
只能通过默认self
的方式在类的内部进行调用,具有最高的访问权限,因此对于一些完全不想暴露的方法,如果只是在类的内部进行调用,就可以用private
方法。而protected
在一定程度上具有跟private
类似的效果,但是protected
可以在类以及子类的内部进行实例化访问,因此protected
可以在一些需要内部继承的调用,又不想完全暴露的需求上使用。
Ruby相关文章
1. Ruby类基础
2. 类的public private protected
3. Ruby yield
4. Ruby双冒号