Quelles sont les différences entre les méthodes "privées", "publiques" et "protégées"?

J'apprends Ruby, et j'en suis arrivé à un point où je suis confus.

Le livre que je suis en utilisant parle private,public et protected methods, mais je suis encore un peu confus. Quelles sont les différences entre chaque?

37
demandé sur the Tin Man 2012-03-27 06:54:29

7 réponses

Public - peut être appelé de n'importe où

Privé - la méthode ne peut pas être appelée en dehors de la portée de la classe. L'objet ne peut envoyer le message à lui-même

ex: le boulanger a bake méthode public, mais break_eggs privé

protégé - vous pouvez appeler les méthodes protégées d'un objet aussi longtemps que l'objet par défaut self est une instance de la même classe que l'objet dont vous êtes la méthode appel de

ex: avec n méthode protégée, c1 demander c2 exécuter c2.n, parce que c1 et c2 sont les deux instances de la même classe

Et le dernier mais non le moindre:

  • Héritage: les sous-classes héritent de la méthode-les règles d'accès de leur super-classe

si "class D < C", alors D affichera le même comportement d'accès que les instances de C

référence: http://www.amazon.com/Ruby-Rails-Techniques-Developers/dp/1932394699

35
répondu Julio Marins 2017-12-07 21:11:36

public les méthodes sont ouvertes à tous. Comme pour private contre protected, je me réfère à "Ruby Méthodes Privées contre les Méthodes Protected":

Quelle est la différence entre "privé" et "protégés" méthodes en Rubis? En Ruby, la principale différence entre un "privé" et la méthode "protégée" est qu'une méthode privée ne peut pas être appelée avec explicite récepteur, tandis qu'une méthode protégée peut. Qu'est ce qu'un "récepteur explicite", vous demandez? Explicite le récepteur est l'objet qui est la réception d'un message. Dans l'exemple suivant, nous avons un récepteur ("parent") et une méthode ('get_name'). L'objet 'parent' est recevoir l'instruction d'exécuter la méthode' get_name'.

31
répondu ScottJShea 2013-10-25 14:11:24

Cocher "Programmation Ruby/Syntaxe/Classes" pour un exemple détaillé et d'explication.

en termes simples, les différences entre private,public et protected les méthodes sont la visibilité de cette méthode dans le programme, un peu comme la lecture seule, la lecture et l'écriture, et presque invisible.

contrairement à certaines autres langues, vous ne pouvez pas cacher complètement une méthode Ruby private, vous ne pouvez accéder aux méthodes privées que pour votre instance d'objet et pas pour toute autre exemple d'objet d'une classe.

Public, bien sûr, est d'une accessibilité totale et les méthodes sont généralement par défaut public, à quelques exceptions près.

les méthodes protégées sont accessibles à partir d'objets de la même classe ou même d'enfants, ce qui n'est pas le cas pour une méthode privée.

6
répondu lifejuggler 2013-10-25 14:10:16

La différence se fera sur Visibilité et comment ils sont affectés par Héritage:

Visibilité:

//Partout / / le Public peut être consulté de l'intérieur et de l'extérieur de la classe.

// dans la classe || tant le privé que le protégé ne sont accessibles que de l'intérieur de la classe.

similarité entre protégé et privé :

  • on peut accéder aux deux à partir de l'extérieur de la classe par une méthode publique.

différences entre protégé et privé sont:

  • méthode Privée ne peut pas être appelée avec un récepteur (même pas avec #self). à moins que ... l'appel d'une méthode du SETTER privé. Si vous essayez de supprimer le récepteur, Ruby créera une variable locale. Le moi est un must dans ce cas.

  • Protégées peuvent ou ne peuvent pas utiliser l'auto.

  • protégé peut accéder à la méthode protégée d'un autre objet qui vient de la même classe, Private ne peut pas.

Quand il s'agit de Héritage:

  • Les méthodes privées ne peuvent être appelées que implicitement (simplement le nom de la méthode)mais pas explicitement (à l'aide de #auto.)

  • protégé peut être appelé dans les deux sens (avec ou sans #self || implicitement ou explicitement).

exemple avec le code ci-dessous :

 class Dog
  attr_accessor :name, :age

  def initialize(n, a)
    self.name = n
    self.age = a
  end

  def accessing_private
    "#{self.name} in human years is #{human_years}. This is secret!"
  end

  def accessing_protected
    "Will this work? " + a_protected_method
  end

  def eat_more_than(other) 
  # accessing other instance's protected method from the same class
    daily_diet < other.daily_diet 
    "#{name} eats more than #{other.name}"
  end

  def boy 
    gender_method("boy") # accessing private setter method
  end

  protected

  def daily_diet 
    age * 2 # the younger, the more they have to eat 
  end

  def a_protected_method
    "Yes, I'm protected!"
  end

  private

  attr_writer :gender

  def gender_method(gender)
    self.gender = gender # private setter method requires self
    "#{name} is a #{gender}"
  end

  def human_years
    age * 8
  end
end

# Create the first object of Dog
blake = Dog.new("Blake", 5)

p blake.accessing_private # "Blake in human years is 16. This is secret!"

p blake.accessing_protected # "Will this work? Yes, I'm protected!"

# Create the second object of Dog
jackson = Dog.new("Jackson", 1)

# Below, protected methods from different objects of the same type/class 
# are proven to share access
p jackson.eat_more_than(blake) # true -> "Jackson eats more than Blake"

# Below, accessing private setter method through a public method.
p blake.boy # Blake is a boy 
5
répondu Maya Novarini 2017-09-01 19:25:52

Laissez-moi vous expliquer Private et protected les méthodes fonctionnent un peu différemment dans Ruby que dans la plupart des autres les langages de programmation. Supposons que vous ayez une classe appelée Foo et une sous-classe SubFoo . Dans des langues comme l' Java,SubFoo n'a pas accès aux méthodes privées définies par Foo . Comme vu dans la Solution, Ruby ne fournit aucun moyen de cacher les méthodes d'une classe de son sub- classe. De cette façon, Ruby’s privé fonctionne comme Javaprotected.

Supposons en outre que vous disposez de deux instances de la classe Foo, a et b. Dans les langues comme Java,a et b peuvent s'appeler private methods. Ruby, vous devez utiliser un protected method pour que. C'est la principale différence entre private et protected méthodes Ruby.

class Foo
  private
  def pri
    'hey I am private of Foo'
  end

  protected
  def prot
    'Hey I am protected of Foo'
  end
end

maintenant sous-classe de Foo

class SubFoo < Foo
  def call_pri_of_foo
    pri
  end

  def call_prot_of_foo
    prot
  end
end

maintenant appel aux accesseurs dans SubFoo

 > sub_foo = SubFoo.new
 => #<SubFoo:0x00000002b56ad8> 
 > sub_foo.call_pri_of_foo
 => "hey I am private of Foo" 
 > sub_foo.call_prot_of_foo
 => "Hey I am protected of Foo"

Jusqu'ici, il semble y avoir pas différence

next_sub_foo = SubFoo.new
 => #<SubFoo:0x00000002b1a0b0>

def next_sub_foo.access_private(child_of_sub_foo)
  child_of_sub_foo.pri
end

def next_sub_foo.access_protected(child_of_sub_foo)
  child_of_sub_foo.prot
end

appel à l'accessor

> next_sub_foo.access_private(sub_foo)
# => NoMethodError: private method `pri' called for #<SubFoo:0x00000002b56ad8>

mais il peut accéder aux méthodes protégées de ses frères et sœurs

> next_sub_foo.access_protected(sub_foo)
# => "Hey I am protected of Foo"

Vous pouvez également voir @tenderlove's blog pour une image plus claire http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html

3
répondu illusionist 2016-03-30 14:48:14

je pense que décomposer un récepteur explicite Est ce qui est important si vous avez des difficultés à saisir le concept.

un récepteur explicite est un objet qui accepte un message.

 person.get_name

personne qui est le récepteur et la méthode "get_name" est de donner des instructions à l'objet "personne" pour effectuer la méthode "get_name".

class Person
    attr_accessor :first_name, :last_name 

  def initialize(first_name, last_name)
    @first_name = first_name
    @last_name = last_name
    puts "And #{phone_number}" # Private method called when initialized
  end

  private 
  def phone_number
    return "XXX-XXX-XXXX"
  end
end


p p1 = Person.new("mike", "jones")


p p1.phone_number # Not within the context of the object instance.

Lorsqu'une méthode est privé, il ne peut être utilisé par d'autres méthodes à l'intérieur de l'objet dont la classe c'est définir.

1
répondu gkstr1 2016-09-17 21:26:50

Etudier les informations que j'ai prises de ici, j'ai étendu les explications à travers les erreurs, et à mon avis, permet de comprendre pourquoi et comment utiliser protégées et non pas privé.

1) protégé:

La ligne num 12 crash car le paramètre reçu est d'une autre classe, le message d'erreur est clair:

v.rb:12:in `==': undefined method `sku' for "Object of another class ==> crash":String (NoMethodError)

2) Privé:

Si supprimer auto de la ligne 8 et 12, et je change protégéprivé, impact, parce que dans la ligne 12, autres ne sait pas sku est:

v.rb:12:in `==': private method `sku' called for #<Product:0x00000001574e68 @name="Bread", @quantity=1> (NoMethodError)

le programme:

class Product
  attr_accessor :name, :quantity

  def initialize(name)
    @name = name
    @quantity = 1

    puts "The SKU is #{self.sku}"
  end

  def == (other)
    self.sku == other.sku
  end

  protected
    def sku
      name.crypt("yo")
    end
end

milk1 = Product.new("Milk")
milk2 = Product.new("Milk")
bread = Product.new("Bread")

puts milk1 == bread

puts milk1 == milk2

puts milk1 == "Object of another class ==> crash"
0
répondu Albert Català 2016-05-25 10:09:40