Rubyのクラスのメソッドの種類について

Rubyのクラスについてインスタンスメソッド、クラスメソッド、メソッドの呼び出し制限によるプライベートメソッドをまとめます。

クラスの基本内容については[先日まとめた記事](https://qiita.com/bellmmm/items/a1292d5143d0f128c009)をご確認ください。  
selfと@の違い、selfと()の省略については[こちらの記事](https://qiita.com/bellmmm/items/f309bcddb71db53da662)をご確認ください。

# インスタンスメソッド
## インスタンスメソッドとは
インスタンスメソッドはクラスのインスタンス(実体)に紐づけられるメソッドです。
## 使い方
クラスの中にメソッドを作成するとインスタンスメソッドになります。後述するクラスメソッドとは異なり、呼び出す際にはインスタンスの作成が必要です。`インスタンス名.メソッド名`で呼び出します。
## 例)Calculationクラスのインスタンスメソッド
```ruby
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クラスのクラスメソッド
```ruby
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クラスのプライベートメソッドの呼び出し
```ruby
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クラスから親クラスのプライベートメソッドを呼び出し
```ruby
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 :メソッド名`と指定する必要があります。

# まとめ
インスタンスメソッドとクラスメソッドの違い、メソッドの呼び出し制限で設定されるプライベートメソッドについてまとめました。プライベートメソッドについて理解するには、実際にいくつかのケースを用意して、どのようなときに呼び出せて、どのような場合は呼び出せないのかを実行してみるのが近道だと感じました。