Rubyのクラスについて自分の備忘録としてまとめます。
クラスとは
クラスはデータの入れ物(データそのものではない)とその処理をまとめたものです。
クラスの使用例
例えば、商品の価格と原価のデータがあり、利益を計算したいと思います。
クラスを使わない場合
クラスを使わない場合、次のように計算することができます。
例1
ringo_name = "りんご"
ringo_genka = 100
ringo_kakak = 200
puts ringo_kakak - ringo_genka #=>100
#putsは引数(文字列)を出力するメソッド。
ichigo_name = "いちご"
ichigo_genka = 200
ichigo_kakak = 400
puts ichigo_kakak - ichigo_genka #=>200
例1では、商品の数が多くなると記載する量が多くなってしまいます。また、ringoと記載するべき場所にichigoと記載してしまうなどの間違いをする可能性があります。
例2
ringo = {name:"りんご", genka:100, kakaku:200}
puts ringo[:kakaku] - ringo[:genka] #=>100
ichigo = {name:"いちご", genka:200, kakaku:400}
puts ichigo[:kakaku] - ichigo[:genka] #=>200
例2では、ハッシュを使っています。例1より記載量が少なく、ハッシュにより商品ごとのデータがまとまっているためringoに関する計算にichigoのデータが間違って入力されるという可能性が低くなっています。
しかし、利益の計算を都度入力しているため、-を+と入力するなどの入力間違いの可能性があります。
クラスを使う場合
クラスを使うとこれらの問題に対応することができます。
冒頭述べた通り、クラスはデータの入れ物とその処理をまとめたものです。
データの入れ物とその処理をまとめたクラスを作り、それに実際のデータを設定して使います。
例3
name
、genka
、kakaku
のデータの入れ物と、利益を得る処理をまとめたものをclass Shohin
とします。クラスを使うためにはまずクラスを定義する必要があります。ここでは実際の計算は行っていません。
Shohinクラスの定義は以下の通りです。
class Shohin
def initialize(name, genka, kakaku)
@name = name
@genka = genka
@kakaku = kakaku
end
def rieki()
return @kakaku - @genka
end
end
まず、クラス名をclass クラス名
と表記し、class クラス名
からend
までの中にdef
とend
で処理をまとめます。
上の例ではクラス名をShohin
とし、
1つ目のdef initialize
で、引数にname、genka、kakakuをとり、それぞれを
@name、@genka、@kakakuに代入しています。
2つ目のdef riekiは引数をとらず、@kakakuから@genkaを引いた値を返しています。
実際のデータの設定と、クラスを使用した利益の計算は以下の通りです。
コードはクラス定義の続きに記載しています。
ringo = Shohin.new("りんご", 100, 200)
puts ringo.rieki() #=>100
ichigo = Shohin.new("いちご", 200, 400)
puts ichigo.rieki() #=>200
データの設定、つまりクラスのデータの入れ物に個別のデータを入れることを、コンストラクトと呼びます。
クラスのコンストラクトはクラス名.new(データ1,データ2,...)
で実行されます。
上記では、Shohin.new()
で実際のデータを入れて、コンストラクトしています。実際のデータを入れコンストラクトしたものを、それぞれをringo
とichigo
という変数に代入しています。この、コンストラクトされてできたデータの実態を持つ変数をインスタンスと呼びます。
コンストラクトする際に入れられたデータはinitialize
でそれぞれの@が付いた変数に代入されます。この@が付いた変数をインスタンス変数と呼びます。インスタンス変数はインスタンスそれぞれに紐づいています。今回の例で言うと、インスタンスringo
のインスタンス変数@name
には"りんご"
が、インスタンスichigo
のインスタンス変数@name
には"いちご"
が、という様にインスタンスごとに違う情報が入力されているということです。
Shohin.new()
で実行される処理はここまでです。
クラス内で定義されている処理をインスタンスメソッドと呼びます。initialize
は特別なメソッドで、コンストラクトの際に実行されます。それ以外のメソッドは、インスタンス名.インスタンスメソッド名
で実行することができます。
上記では、ringo.rieki()
やichigo.rieki()
で実行した返り値をputs
で出力しています。
まとめ
クラスについてまとめました。クラスを使うことで、以下のようなメリットがあることがわかります。
- データとそれに紐づく処理をまとめることができる
- データを入力する手間が少ない
- データを入力する際の間違いが少ない
- データから処理する際の間違いが少ない
クラスには他にも様々な機能があります。クラスを設計する人とそれを使用する人が別の場合を考えると、上記のメリットやクラスの機能を使うことで、設計者は使用者のミスを減らすことができます。これもクラスを使うメリットです。