Rubyのクラスについてインスタンスメソッド、クラスメソッド、メソッドの呼び出し制限によるプライベートメソッドをまとめます。
クラスの基本内容については先日まとめた記事をご確認ください。
selfと@の違い、selfと()の省略についてはこちらの記事をご確認ください。
インスタンスメソッド
インスタンスメソッドとは
インスタンスメソッドはクラスのインスタンス(実体)に紐づけられるメソッドです。
使い方
クラスの中にメソッドを作成するとインスタンスメソッドになります。後述するクラスメソッドとは異なり、呼び出す際にはインスタンスの作成が必要です。インスタンス名.メソッド名
で呼び出します。
例)Calculationクラスのインスタンスメソッド
class Calculation
def addition(a, b, c)
return a+b+c
end
end
cal = Calculation.new
puts cal.addition(1,2,3) #=>6
インスタンス化した後に、インスタンス名.メソッド名
で実行しています。
クラスメソッド
クラスメソッドとは
クラスメソッドはクラスオブジェクトから実行可能なメソッドです。
使い方
クラス名.メソッド名
で呼び出します。クラスメソッドはクラスの中にself.メソッド名
で定義し、インスタンス化不要で使えます。
例)Calculationクラスのクラスメソッド
class Calculation
def self.addition(a, b, c)
return a+b+c
end
end
puts Calculation.addition(1,2,3) #=>6
インスタンス化せずに、クラス名.メソッド名
で実行しています。
メソッドの呼び出し制限とプライベートメソッド
呼び出し制限
メソッドはpublic、private、protectedの3通りの呼び出し制限を持ちます。ここではプライベートに設定されたメソッドであるプライベートメソッドについてまとめます。
プライベートメソッドとは
プライベートメソッドはクラスの外からは呼び出せず、クラス内でのみselfを省略した形で(関数形式で)呼び出すことができるメソッドです。
”プライベートメソッドはレシーバーが指定できないため、クラスの外からは呼び出しができない”と理解されていることもありますが、Ruby2.7以降ではself.メソッド名
のようにselfをつけて呼び出すことができます。しかし、self以外のレシーバーをつけて呼び出すとエラーとなるため、クラスの外から直接呼び出すことはできません。
ここで”直接”呼び出すことができないと記載したのは、次の例にあるように、パブリックメソッド内でプライベートメソッドを呼び出せば、そのパブリックメソッドを実行することでプライベートメソッドの返り値を取り出すことはできるからです。
クラスの継承により親クラスのプライベートメソッドを子クラスの中で関数形式で呼び出すことができます。
プライベートメソッドを使う利点は、外から直接呼び出せないようにアクセス制御を設定することができる点です。
使い方
クラスの中にprivateと宣言してそれ以降にメソッドを定義すると呼び出し制限がprivateになります(定義したメソッドはプライベートメソッドになります)。
なお、先日まとめた記事で紹介したinitialize
というメソッドは、自動的に呼び出し制限がprivateに設定されます。
例1
Calculationクラスのプライベートメソッドの呼び出し
class Calculation
# パブリックメソッド
def public_method
"this is public method"
end
# プライベートメソッドを呼び出すパブリックメソッド
def call_private
private_method
end
# プライベートメソッドをレシーバー付きで呼び出すパブリックメソッド
def call_private_with_receiver(receiver)
receiver.private_method
end
private
# プライベートメソッド
def private_method
"this is private"
end
end
cal=Calculation.new
puts cal.public_method #=>"this is public method"
puts cal.call_private #=>"this is private method"
cal_1=Calculation.new
puts cal_1.call_private_with_receiver(cal) #=>NoMethodError
例2
Calculationクラスを継承したChildクラスから親クラスのプライベートメソッドを呼び出し
class Calculation
# 内容は例1と同じため省略
end
# Calculationクラスを継承したChildクラスを作成
class Child < Calculation
# 親クラスのプライベートメソッドを関数形式で呼び出すパブリックメソッド
def call_private_from_child
private_method
end
end
child = Child.new
puts child.call_private_from_child #=>"this is private method"
上記の通り、
- プライベートメソッドは同じクラス内のパブリックメソッドの中で呼び出すことはできるが、クラスの外から直接呼び出すことはできない。
- private メソッドはself以外のレシーバーを指定して呼び出すことができない(Ruby2.6以前ではselfも不可)。
- クラスを継承すると、子クラスの中で親クラスのプライベートメソッドを関数形式で呼び出すことが可能。
なお、privateと宣言した後にクラスメソッドを作成すると、クラスの外でクラス名.メソッド名
で呼び出すことができてしまいます。これはそのクラスメソッドがprivateメソッドとして定義できていないためです。正しく定義するにはクラス内でprivate_class_method :メソッド名
と指定する必要があります。
まとめ
インスタンスメソッドとクラスメソッドの違い、メソッドの呼び出し制限で設定されるプライベートメソッドについてまとめました。プライベートメソッドについて理解するには、実際にいくつかのケースを用意して、どのようなときに呼び出せて、どのような場合は呼び出せないのかを実行してみるのが近道だと感じました。