クラスとインスタンスを俗世もので例えてみた
rubyを行う上で class
や instance
って切っても切り離せなくて、かなり大事なことなのは初心者の私でも理解できる。(rubyしか勉強してないから他はわからん)
でも文章で理解できても、私はコードにしようと思うと書けないので、わかってないと思うんですね。
だから自分が理解しやすいように、俗世のもので例えたいと思います。
そもそもクラスとインスタンスって?
classとは設計図のようなもので、それ自体には中身がないもの。
instanceはそのclassをもとにして作られた実体、データ。クラス名.newで生成できる
クラスメソッドはクラスから作られた全ての個別の情報によらず、共通の結果を返す動作を定義するメソッド。
インスタンスメソッドはインスタンスの持つ個別の属性に対して、別々に設定できるメソッド
インスタンス変数を用いることで、個々のインスタンスによって別々に設定した属性値を設定できる。
class クラス
def self.メソッド名 #クラスメソッド
処理
end
def メソッド名 #インスタンスメソッド
@変数名 = 値 #インスタンス変数
処理
end
end
クラス名.new #インスタンス生成
インスタンス名.メソッド名 #インスタンスメソッドの呼び出し
クラス名.メソッド名 #クラスメソッドの呼び出し
多分、大体の教材はこう書いてあるのではないでしょうか?
いってる意味はわかるんだ!なるほど!ってなるんだ!
でも、その後にある見本のコードを見ると ? ってなるんだ。
そんな状態でやれ initializeメソッドだの、インスタンス変数は他のメソッドでも使えるだの言われても余計混乱するって!! って感じでした。
コードになると急にとっつきにくくなるので、砕けた表現で例えたいと思います。
某アニメから
まあ、例え方は色々とあると思うんですが、ここは流行りの○○の刃で例えたいと思います。ポ◯モンでもいいと思ったんだけどね!共通する処理が浮かばなかった!!
クラスとインスタンス
先にコードを書いて、一つずつ説明したいと思います。
class Kisatutai
end
tannzirou = Kisatutai.new
zennitu = Kisatutai.new
まあ、こんな感じです。
まずはクラスについてですが、設計図とはよくいったもので、そのまとまりは何を表しているのか、というところです。
今回のクラスは鬼殺隊の人たち。
じゃー鬼殺隊の人って誰いるの? っていうその 誰か が今回はインスタンスになります。
ゲストは炭治郎さんと、善逸さん。
インスタンスメソッド(+属性と属性値)について
というわけで、まずその人の情報を入れないといけないですよね。
今回は 鬼殺隊の 名前
色
呼吸の種類
でグループ分けをします。その一人一人に入れないといけない情報が属性になり、実際にその人が持っている情報が、属性値になるということです。
炭治郎くんも善逸くんも同じ、鬼殺隊というクラスに属しているけど、各使ってる刀も呼吸も違うから情報を入れる必要があるよねってこと。
その個別に行うことを定義するのが インスタンスメソッド なんです。
class Kisatutai
def profile(namae, iro, zokusei) #クラスに属性を指定(名前、刀の色、呼吸の種類)をしている
puts "名前:#{namae}"
puts "刀の色:#{iro}色"
kokyuu = "#{zokusei}の呼吸"
puts "使用呼吸:#{kokyuu}"
end
end
tannzirou = Kisatutai.new
tannzirou.profile("竈門炭治郎", "黒", "水") # ()の中身が属性値
zennitu = Kisatutai.new
zennitu.profile("我妻善逸", "黄", "雷")
=>出力結果
名前:竈門炭治郎
刀の色:黒色
使用呼吸:水の呼吸
名前:我妻善逸
刀の色:黄色
使用呼吸:雷の呼吸
これは、profileメソッドで、この属性を入れてくださいと指定がある為 tannzirou.profile で属性値を入れているというわけです。
これで、二人の細かい情報を入れることができました。
クラスメソッドについて
反対にクラスメソッドは、炭治郎や善逸関係なく、鬼殺隊が全員使える処理のこと。だから、
Kisatutai.メソッド となるんです。
class Kisatutai
def self.zennsyuutyuu #クラスメソッド 誰でも使える(全集中常中は本当は訓練が必要)
puts "全集中常中"
end
end
Kisatutai.zennsyuutyuu #クラスで共通の情報を使った処理
=>出力結果
全集中常中
ひと呼吸
今のところ、ここまでの処理をまとめるとこんな感じです。
class Kisatutai
def profile(namae, iro, zokusei) #クラスに属性を指定(名前、刀の色、呼吸の種類)をしている
puts "名前:#{namae}"
puts "刀の色:#{iro}色"
kokyuu = "#{zokusei}の呼吸"
puts "使用呼吸:#{kokyuu}"
end
def self.zennsyuutyuu #クラスメソッド 誰でも使える(全集中常中は本当は訓練が必要)
puts "全集中常中"
end
end
tannzirou = Kisatutai.new
tannzirou.profile("竈門炭治郎", "黒", "水") # ()の中身が属性値
Kisatutai.zennsyuutyuu #クラスで共通の情報を使った処理
puts "-------------------------------"
zennitu = Kisatutai.new
zennitu.profile("我妻善逸", "黄", "雷")
Kisatutai.zennsyuutyuu #クラスで共通の情報を使った処理
この時点で、もしよければコピペして ruby を実行してもらえると、イメージがつきやすくていいかと思います。
インスタンス変数とinitializeメソッドについて
インスタンス変数の前に、コードを一つ書きます
class Kisatutai
def itinokata(wazamei)
puts "壱の型 #{wazamei}"
end
end
tannzirou = Kisatutai.new
tannzirou.itinokata("水面切り")
Kisatutai.zennsyuutyuu
zennitu.itinokata("霹靂一閃")
=>出力結果
壱の型 水面切り
壱の型 霹靂一閃
みなさんご存知だと思いますが、ほんとはアニメだと "水の呼吸 壱の型 水面切り" ですよね。
この itinokata メソッドに呼吸を足そうと思えば属性と属性値を足せばできるのですが、
プロフィールでも呼吸って使いましたよね?
他のメソッドで定義した変数を別の場所でも使えるのが、インスタンス変数の特徴です。
ですので、さっきのプロフィールの呼吸のところをインスタンス変数にして足せば使い回しができます。
def profile(namae, iro, zokusei)
puts "名前:#{namae}"
puts "刀の色:#{iro}色"
@kokyuu = "#{zokusei}の呼吸" #@koyuuがインスタンス変数
puts "使用呼吸:#{@kokyuu}"
end
def itinokata(wazamei)
puts "#{@kokyuu} 壱の型 #{wazamei}"
end
とこんな感じです。
んで、プロフィールって一番最初に出てきた方がいいじゃないですか。
わざわざ
tannzirou = Kisatutai.new
tannzirou.profile()
って書くのめんどくさいと思うんですよね。どうせ、実行するし、、、
そんな時にインスタンスの生成と同時に行ってくれるのが、 initializeメソッドです。
ですので、 profile を initialize に書き換えます。
def initilize(namae, iro, zokusei)
中略
end
こうすることで、最初からプロフィールを実行してくれます。
まとめ
以上をまとめるとこんな感じです。
class Kisatutai #クラス 設計図(今回はグループ)
def initialize(namae, iro, zokusei) #新しくクラスをつくると勝手に行ってくれるメソッド
#クラスに属性を指定(名前、刀の色、呼吸の種類)をしている
puts "隊員プロフィール"
puts "名前:#{namae}"
puts "刀の色:#{iro}色"
@kokyuu = "#{zokusei}の呼吸" #@koyuuはインスタンス変数
puts "使用呼吸:#{@kokyuu}"
end
def self.zennsyuutyuu #クラスメソッド 誰でも使える(全集中常中は本当は訓練が必要...)
puts "全集中常中"
end
def itinokata(wazamei) #インスタンスメソッド 壱の型 技名 人によって変わる
puts "#{@kokyuu} 壱の型 #{wazamei}!!!!!!"
#インスタンス変数(@kokyuu)はクラス内のインスタンスメソッドであればどこでも使える
end
end
tannzirou = Kisatutai.new("竈門炭治郎", "黒", "水") #インスタンスの生成(属性値あり)
Kisatutai.zennsyuutyuu #クラスで共通の情報を使った処理
tannzirou.itinokata("水面切り") #個別の情報(属性値)を使った処理
puts "------------------------------"
zennitu = Kisatutai.new("我妻善逸", "黄", "雷")
Kisatutai.zennsyuutyuu
zennitu.itinokata("霹靂一閃")
=>出力結果
隊員プロフィール
名前:竈門炭治郎
刀の色:黒色
使用呼吸:水の呼吸
全集中常中
水の呼吸 壱の型 水面切り!!!!!!
------------------------------
隊員プロフィール
名前:我妻善逸
刀の色:黄色
使用呼吸:雷の呼吸
全集中常中
雷の呼吸 壱の型 霹靂一閃!!!!!!
------------------------------
なんとなく、イメージつけたら幸いです。
変数名はあえてローマ字にしてますが、ほんとはわかりやすい英語にしないといけないです(笑)
皆さんの勉強の助けになれば
ご指摘ありましたら、ご連絡ください。
ここまで読んでくださりありがとうございました!!
蛇足
このコード動かせるようにしました。
もしよければコピペして遊んでいただけると、私、とても嬉しいです。
class Kisatutai #クラス 設計図(今回はグループ)
def initialize(namae, iro, zokusei) #新しくクラスをつくると勝手に行ってくれるメソッド
#クラスに属性を指定(名前、刀の色、呼吸の種類)をしている
puts "隊員プロフィール"
puts "名前:#{namae}"
puts "刀の色:#{iro}色"
@kokyuu = "#{zokusei}の呼吸" #@koyuuはインスタンス変数
puts "使用呼吸:#{@kokyuu}"
end
def self.zennsyuutyuu #クラスメソッド 誰でも使える(全集中常中は本当は訓練が必要)
puts "全集中常中"
end
def itinokata(wazamei) #インスタンスメソッド 壱の型 技名 人によって変わる
puts "#{@kokyuu} 壱の型 #{wazamei}!!!!!!"
#インスタンス変数(@kokyuu)はクラス内のインスタンスメソッドであればどこでも使える
end
end
puts "鬼滅の好きなキャラは?"
namae = gets.chomp
puts "ローマ字で入れてください"
name = gets.chomp
puts "その人の刀の色は?"
iro = gets.chomp
puts "その人の呼吸の種類は?"
zokusei = gets.chomp
puts "その人の使う壱の型を教えてください"
wazamei = gets.chomp
puts "------------------------------"
name = Kisatutai.new(namae, iro, zokusei)
Kisatutai.zennsyuutyuu
name.itinokata(wazamei)