public, private 和 protected
在某些情况下,你可能希望限制方法的“可见性”(visibility),以确保定义方法的类之外的代码不能调用它们。
当你的类定义了它所需的各种“实用的”(utility)工具方法以执行它不打算公开使用的某些功能时,这将是很有用的。通过对这些方法施加访问限制,你可以阻止程序员将它们用于自己的恶意目的。这也意味着你将能够在以后阶段中更改这些方法的实现,而不必担心你将破坏其他人的代码。
Ruby 提供了三个级别的方法可访问性:
public
protected
private
顾名思义,public
方法是最容易访问的,private
方法是最不易访问的。除非另有说明,否则你编写的所有方法都是公开(public)的。当一个方法是公共(public)的时,它可以被定义该对象的整个类之外的环境使用。
当方法是私有(private
)的时,它只能由定义该对象的类内的其它方法使用。
一个受保护(protected
)的方法通常以与私有方法相同的方式工作,但具有一个微小但重要的区别:除了对当前对象的方法可见之外,受保护的方法对于具有相同类型并且处于第一个对象作用域内的第二个对象也是可见的。
当你看一个可运行的示例时,私有和受保护方法之间的区别可能更容易理解。思考这个类:
class MyClass
private
def priv
puts( "private" )
end
protected
def prot
puts( "protected" )
end
public
def pub
puts( "public" )
end
def useOb( anOb )
anOb.pub
anOb.prot
anOb.priv
end
end
我已经声明了三个方法,每个方法都有一个级别的可访问性。这些级别是通过在一个或多个方法之前放置 private
,protected
或 public
来设置的。在指定其它某些访问级别之前,指定的可访问性级别对所有后续方法保持有效。
public
,private
和 protected
可能看起来像关键字。但事实上,它们是 Module 类的方法。最后,我的类有一个公共方法 useOb
,它将 MyOb
对象作为一个参数并调用该对象的三个方法 pub
,prot
和 priv
。现在让我们看看如何使用 MyClass 对象。首先,我将创建该类的两个实例:
myob = MyClass.new
myob2 = MyClass.new
现在,我尝试依次调用这三个方法…
myob.pub # This works! Prints out "public"
myob.prot # This doesn't work! I get a 'NoMethodError'
myob.priv # This doesn't work either - another 'NoMethodError'
从上面可以看出,公共(public)方法在调用的对象之外的环境中(正如预期的那样)是可见的。但私有(private)和受保护(protected)的方法都是不可见的。所以,受保护的方法的用途是什么?另一个示例应该有助于理解这一点:
myob.useOb( myob2 )
这一次,我调用了 myob
对象的公共方法 useOb
,并且我将第二个对象 myob2
作为参数传递给它。需要注意的重要一点是 myob
和 myob2
是同一个类的实例。现在,回想一下我之前说过的话:
除了对当前对象的方法可见之外,受保护的方法对于具有相同类型并且处于第一个对象作用域内的第二个对象也是可见的。
这可能听起来像官方话(gobbledygook)。让我们看看是否可以分析一下来理解它。
在程序中,第一个 MyClass 对象(此处为 myob
)在当 myob2
作为参数传递给它的方法时,在它的作用域内就有了第二个 MyClass 对象。当发生这种情况时,你可以认为 myob2
存在于 myob
内部。现在 myob2
共享了容器(containing)对象 myob
的作用域。在这种特殊情况下 - 当同一个类的两个对象在该类定义的作用域内时 - 该类的任何对象的受保护(protected)方法将变得可见。
在本例中,myob2
(这里名为 anob
的参数 - ‘接收’了 myob2
)的受保护方法 prot
变得可见并且可以被执行。然而,它的私有方法仍然是不可见的:
def useOb( anOb )
anOb.pub
anOb.prot # protected method can be called
anOb.priv # but calling a private method results in an error
end