初めに
rubyのclassにおけるprotectedが理解できず調べていたのですが、分からなかった理由はprivateの理解を誤っていたからでした。
今回は思考の整理のため、privateメソッドとprotectedメソッドの違いについてまとめてみます。
共通点
・クラス内かサブクラス内でのみ呼び出せる点(他の言語ではprivateはサブクラス内では呼び出せない場合もあるみたいですが、Rubyではそうではないです)
・レシーバがselfの場合、privateメソッドでもprotectedメソッドでも挙動は変わらない。
bメソッドの中でaメソッドを呼び出している部分は、省略されているだけでその前にselfがあります。
class Parent
def initialize(name)
@name = name
end
def b
a
end
protected #privateでも同じ結果が出ます
def a
puts "a"
end
end
parent = Parent.new("Alice")
parent.b
parent.a #クラス外から呼んでいるのでエラー
相違点
privateメソッドはレシーバがselfの場合でしか呼び出すことができないみたいです(selfは省略してもしなくてもいい)。
だから、「self.メソッド名」ならいけるが、「self以外のレシーバ.メソッド名」とかなら無理です。
逆に、protectedの場合は、レシーバがself以外であっても、そのクラスかサブクラスのインスタンスであれば動きます。それが1番の違いです。
例えば下記のコードの場合、protectedなのでエラーは出ませんがprivateならエラーがでます。
class Parent
def initialize(name)
@name = name
end
def compare_names(other)
if self.protected_method == other.protected_method #ここでotherからprotectedメソッドを呼んでいるが、もしprivateだったらエラーが出る
puts "Names are the same"
else
puts "Names are different"
end
end
protected
def protected_method
@name
end
end
class Child < Parent
end
parent = Parent.new("Alice")
child = Child.new("Alice")
another_parent = Parent.new("Bob")
parent.compare_names(child) # privateならエラー
parent.compare_names(another_parent) # privateならエラー
parent.protected_method # クラス外から呼んでいるのでprivate,protected共にエラー
終わりに
大雑把な説明ですいません。興味がある方は色々調べてみてください。
以上です。ありがとうございました。