访问级别
Ruby 有三个访问级别。他们是 public
,private
和 protected
。
遵循 private
或 protected
关键字的方法也是如此定义的。之前的方法是隐含的 public
方法。
公共方法
公共方法应该描述正在创建的对象的行为。可以从创建的对象的范围之外调用这些方法。
class Cat
def initialize(name)
@name = name
end
def speak
puts "I'm #{@name} and I'm 2 years old"
end
...
end
new_cat = Cat.new("garfield")
#=> <Cat:0x2321868 @name="garfield">
new_cat.speak
#=> I'm garfield and I'm 2 years old
这些方法是公共 ruby 方法,它们描述了初始化新 cat 的行为和 speak 方法的行为。
public
关键字是不必要的,但可以用来转义 private
或 protected
def MyClass
def first_public_method
end
private
def private_method
end
public
def second_public_method
end
end
私人方法
无法从对象外部访问私有方法。它们由对象在内部使用。再次使用 cat 示例:
class Cat
def initialize(name)
@name = name
end
def speak
age = calculate_cat_age # here we call the private method
puts "I'm #{@name} and I'm #{age} years old"
end
private
def calculate_cat_age
2 * 3 - 4
end
end
my_cat = Cat.new("Bilbo")
my_cat.speak #=> I'm Bilbo and I'm 2 years old
my_cat.calculate_cat_age #=> NoMethodError: private method `calculate_cat_age' called for #<Cat:0x2321868 @name="Bilbo">
正如你在上面的示例中所看到的,新创建的 Cat 对象可以在内部访问 calculate_cat_age
方法。我们将变量 age
分配给运行私有 calculate_cat_age
方法的结果,该方法将猫的名称和年龄打印到控制台。
当我们尝试从 my_cat
对象外部调用 calculate_cat_age
方法时,我们会收到一个 NoMethodError
,因为它是私有的。得到它?
受保护的方法
受保护的方法与私有方法非常相似。它们不能以私有方法不能访问对象实例之外的方式访问。但是,使用 self
ruby方法,可以在相同类型的对象的上下文中调用受保护的方法。
class Cat
def initialize(name, age)
@name = name
@age = age
end
def speak
puts "I'm #{@name} and I'm #{@age} years old"
end
# this == method allows us to compare two objects own ages.
# if both Cat's have the same age they will be considered equal.
def ==(other)
self.own_age == other.own_age
end
protected
def own_age
self.age
end
end
cat1 = Cat.new("ricky", 2)
=> #<Cat:0x007fe2b8aa4a18 @name="ricky", @age=2>
cat2 = Cat.new("lucy", 4)
=> #<Cat:0x008gfb7aa6v67 @name="lucy", @age=4>
cat3 = Cat.new("felix", 2)
=> #<Cat:0x009frbaa8V76 @name="felix", @age=2>
你可以看到我们已经为 cat 类添加了一个 age 参数,并创建了三个具有 name 和 age 的新 cat 对象。我们将调用 own_age
保护方法来比较我们的猫对象的年龄。
cat1 == cat2
=> false
cat1 == cat3
=> true
看看,我们能够使用 self.own_age
保护方法检索 cat1 的年龄,并通过在 cat1 中调用 cat2.own_age
来将其与 cat2 的年龄进行比较。