wake-up-neo.com

Was ist der Unterschied zwischen "privaten", "öffentlichen" und "geschützten Methoden"?

Ich lerne Ruby und bin an einen Punkt gekommen, an dem ich verwirrt bin.

In dem von mir verwendeten Buch geht es um private, public und protected methods, aber ich bin immer noch etwas verwirrt. Was sind die Unterschiede zwischen den beiden? 

37
Billjk

Public - kann von überall aufgerufen werden

Private - Die Methode kann nicht außerhalb des Klassenbereichs aufgerufen werden. Das Objekt kann die Nachricht nur an sich selbst senden

beispiel: Der Bäcker hat die bake-Methode als öffentlich, aber break_eggs ist privat

Protected - Sie können die geschützten Methoden eines Objekts aufrufen, solange das Standardobjekt self eine Instanz derselben Klasse ist wie das Objekt, dessen Methode Sie aufrufen

beispiel: Mit n protected kann c1c2 zur Ausführung von c2.n auffordern, da c1 und c2 Instanzen derselben Klasse sind

Zuguterletzt: 

  • Vererbung: Unterklassen erben die Methodenzugriffsregeln ihrer Oberklasse

wenn "Klasse D <C", zeigt D dasselbe Zugriffsverhalten wie Instanzen von C

referenz: http://www.Amazon.com/Ruby-Rails-Techniques-Developers/dp/1932394699

36
Julio Marins

public-Methoden stehen allen offen. Bezüglich private versus protected verweise ich auf " Ruby Private Methods vs. Protected Methods ":

Was ist der Unterschied zwischen privaten und geschützten Methoden in Rubin? In Ruby ist der Hauptunterschied zwischen 'privat' und 'protected' Methode ist, dass eine private Methode nicht mit einer .__ aufgerufen werden kann. expliziter Empfänger, während eine geschützte Methode. Was ist ein "expliziter Empfänger", fragen Sie? Ein expliziter Empfänger ist das Objekt, das empfängt eine Nachricht. Im folgenden Beispiel haben wir einen Empfänger ('parent') und eine Methode ('get_name'). Das 'übergeordnete' Objekt ist Empfangen der Anweisung zum Ausführen der Methode 'get_name'.

32
ScottJShea

Schauen Sie sich " Ruby-Programmierung/Syntax/Klassen " an, um ein ausführliches Beispiel und eine Erklärung zu erhalten.

Vereinfacht ausgedrückt, sind die Unterschiede zwischen den Methoden private, public und protected die Sichtbarkeit dieser Methode im Programm, z.

Im Gegensatz zu einigen anderen Sprachen können Sie eine private Ruby-Methode nicht vollständig ausblenden. Sie können nur auf private Methoden für Ihre Objektinstanz und nicht für jede andere Objektinstanz einer Klasse zugreifen.

Öffentlich ist natürlich die uneingeschränkte Zugänglichkeit, und Methoden werden normalerweise mit einigen Ausnahmen als öffentlich festgelegt.

Geschützte Methoden sind über Objekte derselben Klasse oder sogar untergeordneter Objekte zugänglich, was bei privaten Methoden nicht der Fall ist.

6
lifejuggler

Der Unterschied wird sich auf Sichtbarkeit und deren Auswirkungen auf Vererbung beziehen: 

Sichtbarkeit:

|| Überall || Auf die Öffentlichkeit kann von innerhalb und außerhalb der Klasse zugegriffen werden.

|| Innerhalb der Klasse || Auf Private und Protected kann nur innerhalb der Klasse zugegriffen werden. 

Die Ähnlichkeit zwischen Geschützt und Privat:

  • Auf beide kann von außerhalb der Klasse mit einer öffentlichen Methode zugegriffen werden.

Die Unterschiede zwischen Geschützt und Privat sind: 

  • Private Methode kann nicht mit einem Receiver aufgerufen werden (auch nicht mit #self). FALLS NICHT ... Aufruf einer PRIVATE SETTER-Methode. Wenn Sie versuchen, den Empfänger zu entfernen, erstellt Ruby eine lokale Variable. Selbst ist in diesem Fall ein Muss.

  • Protected kann oder darf nicht selbst verwendet werden. 

  • Protected kann auf die geschützte Methode eines anderen Objekts zugreifen, die von derselben Klasse stammt, Private nicht. 

Wenn es um Vererbung geht: 

  • Private Methoden können nur für Unterklassen implizit aufgerufen werden (einfach nur der Name der Methode) aber nicht explizit (mit #self).

  • Protected kann auf beide Arten aufgerufen werden (mit oder ohne #self || implizit oder explizit). 

Beispiel mit Code unten: 

 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
Maya Novarini

Lassen Sie mich die Private- und protected-Methoden in Ruby etwas anders ausführen als in den meisten anderen Programmiersprachen. Angenommen, Sie haben eine Klasse namens Foo und eine Unterklasse SubFoo ..__ In Sprachen wie Java hat SubFoo keinen Zugriff auf von Foo definierte private Methoden .. Wie in der Lösung beschrieben, bietet Ruby keine Möglichkeit, die Methoden einer Klasse auszublenden aus seinen Unterklassen. Auf diese Weise arbeiten Rubys private Werke wie Javas protected.

Angenommen, Sie haben zwei Instanzen der Klasse Foo, a und b. In Sprachenwie Java können a und bprivate methods der jeweils anderen Seite aufrufen. In Ruby müssen Sie dafür einen protected method verwenden. Dies ist der Hauptunterschied zwischen private- und protected-Methoden in Ruby.

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

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

Jetzt Unterklasse von Foo

class SubFoo < Foo
  def call_pri_of_foo
    pri
  end

  def call_prot_of_foo
    prot
  end
end

Rufen Sie jetzt die Accessoren in SubFoo auf

 > 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"

Bis hierher; Es scheint keinen Unterschied zu geben

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

Rufe jetzt den Accessor an

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

es kann jedoch auf die geschützten Methoden seiner Geschwister zugreifen

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

Sie können auch den Blog von @tenderlove sehen, um ein klareres Bild zu erhalten http://tenderlovemaking.com/2012/09/07/protected-methods-and-Ruby-2-0.html

3
illusionist

Ich denke, es ist wichtig, einen expliziten Empfänger aufzuschlüsseln, wenn Sie Schwierigkeiten haben, das Konzept zu verstehen.

Ein expliziter Empfänger ist ein Objekt, das eine Nachricht annimmt.

 person.get_name

person ist der Empfänger und die Methode "get_name" gibt dem Objekt "person" Anweisungen, um die Methode "get_name" auszuführen.

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.

Wenn eine Methode privat ist, kann sie nur von anderen Methoden innerhalb des Objekts verwendet werden, in dessen Klasse sie definiert ist.

1
gkstr1

Das Studium der Informationen, die ich aus hier genommen habe, habe ich durch Fehler erweitert und meiner Meinung nach hilft es zu verstehen, warum und wie man geschützt und nicht privat verwendet.

1) geschützt:

Die Zeile Nummer 12 stürzt ab, da der Parameter von einer anderen Klasse stammt und die Fehlermeldung eindeutig ist:

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

2) privat:

Wenn Sie self aus Zeile 8 und 12 entfernen und ich protected für private ändere, stürzen Sie ab, weil other nicht weiß, was sku ist :

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

Das Programm:

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
Albert Català