到目前为止, 之前我们定义的方法都能作为实例方法被任意调用. 但是有时候我们可能并不希望这样. 例如, 一些处理方法, 一般不会公开给外部使用.
Ruby提供了3中方法的访问级别, 我们可以按照需求来灵活调整.
- public --- 以实例方法的形式向外部公开该方法
- private --- 在指定接收者的情况下, 不能调用该方法(只能使用缺省接收者的方式调用该方法, 因此无法从实例的外部访问)
- protected --- 在同一个类中时可将该方法作为实例方法调用.
在修改方法的访问级别时, 我们会为这3个关键字指定表示方法名的符号.
class AccTest
def pub
puts "pub is public method."
end
public :pub # 把 pub 方法设定为 public(默认就是 public, 可以省略)
def priv
puts "priv is private method."
end
private :priv # 把 priv 方法设定为 private.
end
AccTest.new.pub
AccTest.new.priv # 报错
AccTest 这两个方法, pub 方法可以正常调用. 但在调用priv方法时报错( private method `priv' called for #<AccTest:0x007fbde88358f8> (NoMethodError))
希望统一定义多个方法的访问级别时, 可以使用下面的语法.
class AccTest
public # 不指定参数时,
# 以下的方法都被定义为
def pub
puts "pub is public method."
end
private # 以下的方法都被定义为 private
def priv
puts "priv is private method."
end
end
没有指定访问级别的方法默认为 public
, 但 initialize
方法是个例外, 他通常会被定义为 private
定义为 protected 的方法, 在同一个类中(及其子类)中可作为实例方法使用, 而在除此以外的地方则无法使用.
class Point
attr_accessor :x, :y
protected :x=, :y= # 将 setter 方法设置受保护的, 在同一个类中可作为实例方法使用. 除此以外的地方无法调用
def initialize(x:, y:)
@x, @y = x, y
end
def swap() # 交换 x, y 的值
self.x, self.y = self.y, self.x # 在同一个类中 x=, y=
# 可以被调用
return self
end
end
point = Point.new(x: 10, y: 20)
puts "x = #{point.x} y = #{point.y}" #=> x = 10 y = 20
point.swap
puts "x = #{point.x} y = #{point.y}" #=> x = 20 y = 10
point.x = 222 #=> 报错(protected method `x=' called for #<Point:0x007fe6420257f8 @x=20, @y=10> (NoMethodError))
网友评论