访问控制

Java 与 Ruby 的访问控制的比较: 如果在 Java 中将方法声明为 private,则只能通过同一类中的其他方法访问它。如果一个方法被声明为 protected,则可以由同一个包中存在的其他类以及该类在不同包中的子类访问。当一个方法公开时,每个人都可以看到它。在 Java 中,访问控制可见性概念取决于这些类在继承/包层次结构中的位置。

而在 Ruby 中,继承层次结构或包/模块不适合。关键在于哪个对象是方法的接收者

**对于 Ruby 中的私有方法,**永远不能使用显式接收器调用它。我们可以(仅)使用隐式接收器调用私有方法。

这也意味着我们可以从声明的类中调用私有方法以及此类的所有子类。

class Test1
  def main_method
    method_private
  end

  private
  def method_private
    puts "Inside methodPrivate for #{self.class}"
  end
end

class Test2 < Test1
  def main_method
    method_private
  end
end

Test1.new.main_method
Test2.new.main_method

Inside methodPrivate for Test1
Inside methodPrivate for Test2

class Test3 < Test1
  def main_method
    self.method_private #We were trying to call a private method with an explicit receiver and if called in the same class with self would fail.
  end
end

Test1.new.main_method
This will throw NoMethodError

You can never call the private method from outside the class hierarchy where it was defined.

**** 可以使用隐式接收器调用受保护的方法,就像私有一样。另外,如果接收器是自身同一类的对象,则受保护的方法也可以由显式接收器(仅)调用。

class Test1
  def main_method
    method_protected
  end

  protected
  def method_protected
    puts "InSide method_protected for #{self.class}"
  end
end

class Test2 < Test1
  def main_method
    method_protected # called by implicit receiver
  end
end

class Test3 < Test1
  def main_method
    self.method_protected # called by explicit receiver "an object of the same class"
  end
end

InSide method_protected for Test1
InSide method_protected for Test2
InSide method_protected for Test3

class Test4 < Test1
  def main_method
    Test2.new.method_protected # "Test2.new is the same type of object as self"
  end
end

Test4.new.main_method

class Test5
  def main_method
    Test2.new.method_protected
  end
end

Test5.new.main_method
This would fail as object Test5 is not subclass of Test1

考虑具有最大可见性的 Public 方法

摘要

  1. 公共: 公共方法具有最大可见性

  2. 受保护: 可以使用隐式接收器调用受保护的方法,就像私有一样。另外,如果接收器是自身同一类的对象,则受保护的方法也可以由显式接收器(仅)调用。

  3. Private: **对于 Ruby 中的私有方法,**永远不能使用显式接收器调用它。我们可以(仅)使用隐式接收器调用私有方法。这也意味着我们可以从声明的类中调用私有方法以及此类的所有子类。