【Ruby】クラスメソッドとインスタンスメソッドの違いを「たい焼きの型」で理解する
RubyやRailsを学び始めた頃につまずきやすい「クラスメソッド」と「インスタンスメソッド」の違いについて整理しました。
「なぜ self. をつけるのか?」を「たい焼きの型」の例えを使ってスッキリ理解していきます!
1. なぜ self. をつけるの?
結論から言うと、Rubyでは def の後ろに何をつけるかで「誰がその処理を実行できるか」が決まるからです。
| 定義の書き方 | 種類 | 呼び出し方(誰が実行できるか) |
|---|---|---|
def self.total_count |
クラスメソッド | クラス自身(Taiyaki.total_count) |
def taste |
インスタンスメソッド | 個々のデータ(インスタンス)(my_taiyaki.taste) |
self は「自分自身」という意味です。
class Taiyaki の中で self. と書くと、「Taiyaki クラス自身」を指すことになります。
2. たとえで考える(たい焼きの型とたい焼き)
オブジェクト指向の基本ですが、以下のように例えるとイメージしやすくなります。
- クラス(Taiyaki) = たい焼きの金型
- インスタンス(my_taiyaki) = 金型から作られた1個1個のたい焼き
① クラスメソッド(self.total_count)
「型(金型)」に対する操作です。
金型に向かって「今まで焼いた全種類の合計数を教えて!」と頼むようなイメージです。
Taiyaki というクラス(型)に対して直接実行します。
② インスタンスメソッド(taste)
「1個のたい焼き」に対する操作です。
「このたい焼きは何味?」と、出来上がった特定の1個(データ)に対して尋ねるイメージです。
生成された個別のインスタンスに対して実行します。
3. サンプルコードと実行例
実際にRubyのコードで書いて確認してみましょう。
クラスの定義
class Taiyaki
attr_accessor :flavor
# 作成されたたい焼きの数を保持するクラス変数
@@count = 0
# 追記: ※実務(特に継承を使う場合)では @@ は予期せぬ動きをすることがあるため、
# 以下のような代替手段が使われることが多いです。
#
# ・Rubyの言語機能として避けたい場合 → クラスインスタンス変数(@count)を使い、
# self.count のような読み取り用メソッドを自分で用意する
# ・ActiveRecordのモデルの場合 → そもそも自前でカウントを持たず、
# DBに保存されているレコード数を Taiyaki.count で直接数える
def initialize(flavor)
@flavor = flavor
@@count += 1
end
# クラスメソッド(現在の合計個数を返す)
def self.total_count
"今まで焼いたたい焼きの合計は #{@@count} 個です!"
end
# インスタンスメソッド
def taste
"#{@flavor}味のたい焼きです!"
end
end
実行結果と返り値
① クラスメソッドの呼び出し
クラス(Taiyaki)に対して直接呼び出します。
# たい焼きを2個作る
Taiyaki.new('あんこ')
Taiyaki.new('カスタード')
# クラス全体に合計数を問い合わせる
Taiyaki.total_count
# => "今まで焼いたたい焼きの合計は 2 個です!"
② インスタンスメソッドの呼び出し
まず Taiyaki.new で1つのインスタンスを作り、そのオブジェクトに対して呼び出します。
# あんこ味のたい焼きを作る(インスタンス化)
my_taiyaki = Taiyaki.new('あんこ')
# 作ったたい焼きに対してメソッドを実行
my_taiyaki.taste
# => "あんこ味のたい焼きです!"
4. まとめ
-
self. がつく(クラスメソッド)
クラス自身(型)が実行する処理 -
self. がつかない(インスタンスメソッド)
生成されたオブジェクト(データ1件)が実行する処理
「型全体への質問か?」「できた1個のデータへの質問か?」を意識すると、どちらで定義すべきかすんなり判断できるようになります!