Posted at

Rubyのクラスメソッドとインスタンスメソッドの例

More than 3 years have passed since last update.


経緯

何人かの方にRubyを教える機会があり、クラスメソッドとインスタンスメソッドの使い分けが

書籍などの例だけだと分かりにくい、という相談を受けました。

そのため記事にまとめることにしました。


対象読者

オブジェクト言語の学習経験が無く、入門書を呼んでいる最中。

クラス、インスタンス、メソッドの概念については


  • 鯛焼きの型と中身

  • 動物クラスと犬クラス、猫クラス

そんな説明を読んで、ぼんやりとイメージがつかめている、

という想定です。


クラスメソッドとインスタンスメソッド


クラスメソッド

クラスオブジェクトから実行可能なメソッドです。



  • def self.method_name でクラスメソッドを定義

class Hoge

def self.hoge
puts "hoge"
end
end
Hoge.hoge # => hoge

selfHogeでもよい



  • class << self 内でクラスメソッドを定義

class Hoge

class << self
def hoge
puts "hoge"
end
end
end
Hoge.hoge # => hoge

selfHogeでもよい


インスタンスメソッド

インスタンスオブジェクトから実行可能なメソッドです。

class Hoge

def hoge
puts "hoge"
end
end
Hoge.new.hoge # => hoge


クラスメソッドとインスタンスメソッドの使い分け


仕様


  • Personクラスを定義する

  • Personは名前、年齢、性別を持つ

  • Personは人数を保持、取得できる(インスタンスの数をカウントし、外部から確認するためのインターフェースを持つ)

  • Personのインスタンスは三つの作成方法がある


    • Person.new


      • 名前・年齢・性別を指定して初期化



    • Person.male


      • 名前・年齢を指定し、内部的に男性として初期化



    • Person.female


      • 名前・年齢を指定し、内部的に女性として初期化





  • Personのインスタンスは挨拶をする


    • Person#hello を定義




プログラム

class Person

@@size = 0
FEMALE = :female
MALE = :male

def self.male(name, age)
new(name, age, MALE)
end

def self.female(name, age)
new(name, age, FEMALE)
end

def self.size
@@size
end

def initialize(name, age, sex)
@@size += 1
@name, @age, @sex = name, age, sex
end

def hello
puts <<-EOS
こんにちわ。
私は
#{@name} です。
年齢は
#{@age} です。
性別は
#{@sex} です。
EOS
end
end

people = [
Person.new('tanaka', 34, Person::MALE),
Person.new('suzuki', 23, Person::FEMALE),
Person.male('sato', 45),
Person.female('honda', 65)
]

people.each { |person|person.hello }

puts "#{Person.size}人います"


出力

こんにちわ。

私は tanaka です。
年齢は 34 です。
性別は male です。
こんにちわ。
私は suzuki です。
年齢は 23 です。
性別は female です。
こんにちわ。
私は sato です。
年齢は 45 です。
性別は male です。
こんにちわ。
私は honda です。
年齢は 65 です。
性別は female です。
4人います


まとめ

クラスに属するメソッド=クラスメソッドはPerson自身に関する情報の

変更や参照の役割をもっています。

今回だと Person.malePerson.femalePerson.sizeです。

インスタンスに属するメソッドは、個別のインスタンスに関する情報の

変更や参照の役割りを持っています。

今回だと Person#helloです。