访问级别

Ruby 有三个访问级别。他们是 publicprivateprotected

遵循 privateprotected 关键字的方法也是如此定义的。之前的方法是隐含的 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 关键字是不必要的,但可以用来转义 privateprotected

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 的年龄进行比较。