Rubyを学んでいて、混乱するところまで来ました。
私が使用している本はprivate
、public
、およびprotected methods
について話していますが、それでも少し混乱しています。それぞれの違いは何ですか?
Public-どこからでも呼び出すことができます
Private-メソッドをクラススコープ外で呼び出すことはできません。オブジェクトはそれ自体にのみメッセージを送信できます
例:パン屋はbake
メソッドをパブリックとして持っていますがbreak_eggs
は非公開です
Protected-デフォルトのオブジェクトself
がそのオブジェクトと同じクラスのインスタンスである限り、オブジェクトの保護されたメソッドを呼び出すことができますあなたが呼んでいるメソッド
例:n
保護されたメソッド、c1
はc2
を実行するにはc2.n
、なぜならc1
およびc2
は両方とも同じクラスのインスタンスです
そして最後に重要なことですが:
「クラスD <C」の場合、DはCのインスタンスと同じアクセス動作を示します
参照: http://www.Amazon.com/Ruby-Rails-Techniques-Developers/dp/1932394699
public
メソッドは誰でも利用できます。 private
とprotected
については、「 Rubyプライベートメソッドと保護されたメソッド 」を参照しています。
Rubyの「プライベート」メソッドと「保護」メソッドの違いは何ですか? Rubyでは、「プライベート」メソッドと「保護」メソッドの主な違いは、プライベートメソッドを明示的なレシーバーで呼び出すことはできませんが、保護されたメソッドはできることです。 「明示的な受信者」とは何ですか?明示的な受信者は、メッセージを受信するオブジェクトです。次の例では、レシーバー( 'parent')とメソッド( 'get_name')があります。 「親」オブジェクトが「get_name」メソッドを実行するための命令を受け取っています。
詳細な例と説明については、「 Rubyプログラミング/構文/クラス 」を確認してください。
簡単に言えば、private
、public
、およびprotected
メソッドの違いは、プログラム内でのそのメソッドの可視性であり、読み取り専用、読み取りおよび書き込みのようなもので、ほとんど見えません。 。
他の一部の言語とは異なり、Rubyプライベートメソッドを完全に非表示にすることはできません。オブジェクトのインスタンスのプライベートメソッドにのみアクセスでき、クラスの他のオブジェクトインスタンスにはアクセスできません。
もちろんパブリックは完全なアクセシビリティであり、メソッドは通常いくつかの例外を除いてデフォルトでパブリックに設定されています。
プロテクトメソッドには、同じクラスのオブジェクトや子からもアクセスできますが、プライベートメソッドの場合はそうではありません。
違いはVisibilityとそれらがInheritanceによってどのように影響を受けるかです:
可視性:
|| どこでも||クラスの内外からパブリックにアクセスできます。
|| クラス内|| PrivateとProtectedの両方は、クラス内からのみアクセスできます。
ProtectedとPrivateのsimilarity:
ProtectedとPrivateのdifferencesは次のとおりです。
プライベートメソッドは、レシーバーでは呼び出せません(#selfでも呼び出せません)。 [〜#〜] unless [〜#〜]...PRIVATE SETTERメソッドを呼び出す。レシーバーを削除しようとすると、Rubyはローカル変数を作成します。この場合、Selfは必須です。
保護対象は自己を使用する場合と使用しない場合があります。
Protectedは、同じクラスの別のオブジェクトのprotectedメソッドにアクセスできますが、Privateはできません。
それがになるとき継承:
プライベートメソッドは、サブクラスで暗黙的にのみ呼び出すことができます(単にメソッドの名前のみ)が明示的には呼び出せません(#selfを使用)。
Protectedは両方の方法で呼び出すことができます(#self ||の有無にかかわらず、暗黙的または明示的に)。
以下のコードの例:
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
Private
メソッドとprotected
メソッドの動作について、Ruby
と他のほとんどのプログラミング言語では少し異なります。 Foo
というクラスとSubFoo
というサブクラスがあるとします。 Java
などの言語では、SubFoo
はFooで定義されたプライベートメソッドにアクセスできません。ソリューションに見られるように、Rubyは、クラスのメソッドをサブクラスから隠す方法を提供しません。このように、Ruby
のプライベートは、Java
のprotected
のように機能します。
さらに、Fooクラスの2つのインスタンス、a
とb
があるとします。 Java
、a
、b
などの言語では、お互いのprivate methods
を呼び出すことができます。 Ruby
では、そのためにprotected method
を使用する必要があります。これは、private
のprotected
メソッドとRuby
メソッドの主な違いです。
class Foo
private
def pri
'hey I am private of Foo'
end
protected
def prot
'Hey I am protected of Foo'
end
end
今Foo
のサブクラス
class SubFoo < Foo
def call_pri_of_foo
pri
end
def call_prot_of_foo
prot
end
end
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"
ここまで;違いはないようです
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
アクセサを呼び出しています
> next_sub_foo.access_private(sub_foo)
# => NoMethodError: private method `pri' called for #<SubFoo:0x00000002b56ad8>
しかし、兄弟の保護されたメソッドにアクセスできます
> next_sub_foo.access_protected(sub_foo)
# => "Hey I am protected of Foo"
より明確な画像については、@tenderlove
のブログもご覧ください http://tenderlovemaking.com/2012/09/07/protected-methods-and-Ruby-2-0.html
明示的なレシーバーを分解することは、コンセプトを理解するのに問題がある場合に重要だと思います。
明示的な受信者は、メッセージを受け入れるオブジェクトです。
person.get_name
personはレシーバであり、メソッド「get_name」はオブジェクト「person」にメソッド「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.
メソッドがプライベートの場合、そのクラスが定義されているオブジェクト内の他のメソッドでのみ使用できます。
私が得た情報 here を研究して、エラーを通して説明を拡張しました。私の意見では、非公開ではなく保護を使用する理由と方法を理解するのに役立ちます。
1)保護:
受信したパラメーターが別のクラスからのものであるため、行num 12がクラッシュし、エラーメッセージは明らかです。
v.rb:12:in `==': undefined method `sku' for "Object of another class ==> crash":String (NoMethodError)
2)プライベート:
8行目と12行目からselfを削除し、protectedを変更した場合private、12行目でクラッシュotherは何を知らないskuは:
v.rb:12:in `==': private method `sku' called for #<Product:0x00000001574e68 @name="Bread", @quantity=1> (NoMethodError)
プログラム:
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"