为什么Ruby既有私有方法又有受保护的方法?

为什么Ruby既有私有方法又有受保护的方法?,ruby,language-design,access-specifier,Ruby,Language Design,Access Specifier,在阅读之前,我认为Ruby中的访问控制是这样工作的: public-可由任何对象访问(例如Obj.new.public\u方法) protected-只能从对象本身以及任何子类中访问 private-与protected相同,但子类中不存在该方法 但是,protected和private的作用似乎是相同的,只是您不能使用显式接收器调用private方法(即self.protected\u方法工作,但self.private\u方法不工作) 这有什么意义?什么情况下您不希望使用显式接收器调用方

在阅读之前,我认为Ruby中的访问控制是这样工作的:

  • public
    -可由任何对象访问(例如
    Obj.new.public\u方法
  • protected
    -只能从对象本身以及任何子类中访问
  • private
    -与protected相同,但子类中不存在该方法
但是,
protected
private
的作用似乎是相同的,只是您不能使用显式接收器调用
private
方法(即
self.protected\u方法
工作,但
self.private\u方法
不工作)


这有什么意义?什么情况下您不希望使用显式接收器调用方法?

受保护的
方法可以由定义类或其子类的任何实例调用

private
方法只能从调用对象内部调用。您不能直接访问另一个实例的私有方法

下面是一个快速实用的示例:

def compare_to(x)
 self.some_method <=> x.some_method
end

考虑Java中的私有方法。当然,它可以从同一个类中调用,但也可以由同一个类的另一个实例调用:

public class Foo {

   private void myPrivateMethod() {
     //stuff
   }

   private void anotherMethod() {
       myPrivateMethod(); //calls on self, no explicit receiver
       Foo foo = new Foo();
       foo.myPrivateMethod(); //this works
   }
}
因此——如果调用方是同一类的不同实例——可以说,我的私有方法实际上可以从“外部”访问。这实际上使它看起来不那么私密

另一方面,在Ruby中,私有方法实际上意味着只对当前实例私有。这就是移除显式接收器选项所提供的


另一方面,我当然应该指出,在Ruby社区中,完全不使用这些可见性控件是很常见的,因为Ruby为您提供了绕过它们的方法。与Java世界不同的是,趋势是让一切都可以访问,并相信其他开发人员不会把事情搞砸。

区别
  • 任何人都可以调用您的公共方法
  • 您可以调用受保护的方法,您的类(或子类)的另一个成员可以从外部调用受保护的方法。没有其他人可以
  • 只有您可以调用私有方法,因为它们只能由
    self
    的隐式接收器调用即使你也不能调用
    self。有些方法是私有的
    ;您必须调用
    private\u方法
    ,并隐含
    self
    • 指出:“然而,有一个例外。如果你有一个私有方法age=,你可以(而且必须)用self调用它,把它和局部变量分开。”
    • 由于
      self
      接收器可以是显式的,因此允许使用
      self.some\u private\u方法。(即使运行时值与
      self
      相同,仍然不允许使用任何其他显式接收器)
在Ruby中,这些区别只是一个程序员对另一个程序员的建议非公开方法是一种表达“我保留更改此项的权利;不要依赖它”的方式。但是您仍然可以使用
send
的锋利剪刀,并且可以调用任何您喜欢的方法

简短的教程 Ruby中的私有方法: 如果一个方法在Ruby中是私有的,那么它就不能被显式接收器(对象)调用。只能隐式调用它。它可以由中描述它的类以及该类的子类隐式调用

First Three types of access specifiers and those define thier scope.
1.Public    ->  Access anywhere out side the class.
2.Private   ->  Can not access outside the class. 
3.Protected ->  This Method not access anywhere this method define 
                scope.

But i have a solution for this problem for all method how to access explain in depth. 

class Test
attr_reader :name
def initialize(name)
  @name = name
end

def add_two(number)
  @number = number 
end

def view_address
  address("Anyaddress")
end

private 
def address(add)
   @add = add
end

protected 
def user_name(name)
  # p 'call method'
  @name = name
end
end

class Result < Test
def new_user
  user_name("test355")
end
end
以下示例将更好地说明这一点:

1) 具有私有方法类\u名称的动物类

class Animal
  def intro_animal
    class_name
  end
  private
  def class_name
    "I am a #{self.class}"
  end
end
在这种情况下:

n = Animal.new
n.intro_animal #=>I am a Animal
n.class_name #=>error: private method `class_name' called
  n= Amphibian.new
  n.intro_amphibian #=>I am a Amphibian
  n.class_name #=>error: private method `class_name' called
n= Animal.new
n.animal_call #=> protect_me called from Animal
n.protect_me #=>error: protected method `protect_me' called
n= Tree.new
n.tree_call #=>error: protected method `protect_me' called for #<Mammal:0x13410c0>
2) 两栖动物的一个亚类,称为两栖动物:

class Amphibian < Animal
  def intro_amphibian
    class_name
  end 
end 
如您所见,只能隐式调用私有方法。它们不能被显式接收者调用。出于同样的原因,不能在定义类的层次结构之外调用私有方法

Ruby中受保护的方法: 如果一个方法在Ruby中受保护,那么定义类及其子类都可以隐式调用它。此外,只要接收者是self或与self的类别相同,显式接收者也可以调用它们:

1) 具有受保护方法protect\u me的动物类

class Animal
  def animal_call
    protect_me
  end
  protected
  def protect_me
    p "protect_me called from #{self.class}"
  end  
end
在这种情况下:

n = Animal.new
n.intro_animal #=>I am a Animal
n.class_name #=>error: private method `class_name' called
  n= Amphibian.new
  n.intro_amphibian #=>I am a Amphibian
  n.class_name #=>error: private method `class_name' called
n= Animal.new
n.animal_call #=> protect_me called from Animal
n.protect_me #=>error: protected method `protect_me' called
n= Tree.new
n.tree_call #=>error: protected method `protect_me' called for #<Mammal:0x13410c0>
2) 从动物类遗传而来的哺乳动物类

class Mammal < Animal
  def mammal_call
    protect_me
  end
end 
3) 从动物类遗传而来的两栖类(与哺乳动物类相同)

4) 一个叫做Tree的类

class Tree
  def tree_call
    Mammal.new.protect_me #Receiver is not same as self
  end
end
在这种情况下:

n = Animal.new
n.intro_animal #=>I am a Animal
n.class_name #=>error: private method `class_name' called
  n= Amphibian.new
  n.intro_amphibian #=>I am a Amphibian
  n.class_name #=>error: private method `class_name' called
n= Animal.new
n.animal_call #=> protect_me called from Animal
n.protect_me #=>error: protected method `protect_me' called
n= Tree.new
n.tree_call #=>error: protected method `protect_me' called for #<Mammal:0x13410c0>
n=Tree.new
n、 tree_call#=>错误:已调用受保护的方法“protect_me”#

Ruby中的子类可以访问私有方法的部分原因是,类的Ruby继承比模块包含更简单——在Ruby中,类实际上是一种提供继承的模块,等等

这意味着基本上一个子类“包含”了父类,因此父类的函数(包括私有函数)实际上也在子类中定义


在其他编程语言中,调用方法涉及将方法名称冒泡到父类层次结构中,并查找响应该方法的第一个父类。相反,在Ruby中,虽然父类层次结构仍然存在,但父类的方法直接包含在已定义的子类的方法列表中。

Java访问控制与Ruby的比较:如果方法在Java中声明为私有,它只能由同一类中的其他方法访问。如果一个方法被声明为protected,那么它可以被同一个包中的其他类以及不同包中的类的子类访问。当一个方法是公共的时,它对每个人都是可见的。在Java中,访问控制可见性概念取决于这些类在继承/包层次结构中的位置

而在Ruby中,继承层次结构或包/模块不适合。都是关于w