こんにちは!Webコーダー・プログラマーの貝原(@touhicomu)です。
今日は、Rubyのclassの定義、newメソッド、inistializeメソッドについて解説します。
この記事では、
- classを定義する方法
- classをnewで作成する方法
- newとinitializeの関係
という基本的な内容から、
- initializeの基本的な使い方
- initializeの応用的な使い方
などの応用的な使い方に関しても学習していきます。
このページで、Rubyの classの定義、newメソッド、inistializeメソッドの使い方をよく把握して自分のスキルとしていきましょう!
classとは
classとは、プログラムの中で使う変数などのデータとそのデータを取り扱うメソッドをひとかたまりにまとめたものです。
データはclassのメソッドにより値を取得したり値を変更したりするようにします。
このようにすることで、classのデータを取得するコード、変更するコードがclassの中だけに集まることになります。
このことにより、コードを保守したり、今後の開発の進捗や仕様変更時に、コードを変更する箇所を、classのデータやメソッドを変更するだけですみます。
このように、classを導入することによりコードの保守や変更に対して、開発効率が高まるというメリットがあります。
classを定義する方法
Rubyでclassを使うには、まず、コード中でclassを定義する必要があります。
以下、疑似コードで確認しましょう。
class クラス名 def initialize() 処理1 処理2 処理3 ・・・・ end end
上のコードは、classを定義するのに最低限のコードです。
まず、classの後にクラス名があります。
また、class~endの間にinitializeメソッドがあります。
initializeメソッドはclassがnewされた際に呼び出されるメソッドで、主にclassのデータの初期化処理を行います。
まずは、コード中でclassの定義は上の例のように行うということを覚えておいてください。
classをnewで作成する方法
classの定義はしましたが、そのままではclassをコード中で使用できません。
classのnewメソッドによって、classをインスタンス化する必要があります。
インスタンス化とは、classの定義をもとに新たな変数を作成することです。
具体的な例を見てみましょう。
class Hello # クラスの初期化メソッド def initialize end # クラスのインスタンスメソッド def talk puts "hello, world" end end # newメソッドによるclassの初期化 hello = Hello.new # Helloクラスのtalkメソッドを実行 hello.talk
実行結果:
hello, world
上のコードでは、Hello.newメソッドを使って、Helloクラスをインスタンス化、つまり変数化しています。
その後、変数helloに対してtalkメソッドを実行するよう命令しています。
その結果、Helloクラスのtalkメソッドが実行され、「hello, world」が出力されています。
このように、classは定義したままでは使用できず、newメソッドによりインスタンス化して初めて、classのメソッドが使用できるようになります。
newとinitializeの関係
今までの章でclassとnewメソッドに関係がわかりました。
では、initializeメソッドはどのような用途に使用されるのでしょうか?
initializeメソッドはnewメソッドが呼び出された際に呼び出されます。
また、newメソッドに渡された変数も、そのままinitializeメソッドに渡されます。
これを利用し、initializeメソッドでは引数を元にclassのデータの初期化を行います。
これがinitializeメソッドの主な用途です。
実際のサンプルコードを見ていきましょう。
class Hello # 名前を保持するクラス変数 @@name = nil # クラスの初期化メソッド def initialize(name) @@name = name end # クラスのインスタンスメソッド def talk puts "hello, #{@@name}" end end # classのnewメソッドに引数を渡す hello = Hello.new("jobs") # newメソッドからinitializeメソッドに渡って初期化された名前が使用される hello.talk
実行結果:
hello, jobs
以上のように、newメソッドに渡した引数がinitializeメソッドの引数nameとして渡されています。
initializeメソッドでは引数nameを元にクラス変数@@nameを初期化しています。
最後に、変数helloに対しtalkメソッドを実行し、クラス変数@@nameに従った出力を行っています。
クラス変数がわからないという方はこちらの記事を参考にしてください。
クラス変数、インスタンス変数、クラスインスタンス変数の違いがわかりやすくまとめられています。
initializeの基本的な使い方
initializeを使う方法
前章でも述べた通り、Rubyのクラスのinitializeメソッドはクラスがnewされた際に一度だけ実行されるメソッドです。
initializeメソッドはクラスの初期化を行いことが主な役目です。
もう一つ、実際にサンプルコードを確認してみましょう。
class Hello def initialize(username) # インスタンス変数@usernameに引数を代入 @username = username end def talk # インスタンス変数を使って出力 puts "hello, " + @username.to_s end end # classをnewメソッドを使ってインスタンス化 hello = Hello.new("Kevin") # helloメソッドを呼び出し hello.talk
実行結果:
hello, Kevin
上のコードでは、クラス変数の代わりにクラスのインスタンス変数を使用しています。
classのインスタンス化時に、newの引数に”Kevin”を与えて実行しています。
newが呼ばれた際にHelloクラスのinitializeメソッドが呼び出され、newの引数がinitializeの引数に渡されます。
initializeでは、引数をもとにインスタンス変数@usernameを初期化しています。
その後Helloクラスのtalkメソッドを呼び出した際に、@usernameがきちんと初期化した通り表示されています。
このように、newメソッドに渡した引数をinitializeメソッドでクラス変数やインスタンス変数を初期化します。
その後、talkなどのインスタンスメソッドで初期化されたクラス変数やインスタンス変数を使用し、データを加工して実行することがclassとnew、initializeの基本的な使用方法です。
複数のinitializeは定義できない
initializeは複数定義してオーバーロードできません。
実際に例をみてみましょう。
class Hello # 一つ目のinitialize def initialize(he) @he = he end # 二つ目のinitalize def initialize(he,her) @he = he @her = her end def hello puts "hello, Mt." + @he.to_s + " and Ms." + @her.to_s end end # 一つ目のinitializeは、上書きされて存在しないので、エラー #hello = Hello.new("Kevin") #=>wrong number of arguments (given 1, expected 2) (ArgumentError) # 二つ目のinitializeは一つ目のinitializeを上書きして存在している hello = Hello.new("Kevin", "Jane") #=>hello, Mt.Kevin and Ms.Jane hello.hello
実行結果:
hello, Mt.Kevin and Ms.Jane
Helloクラスの一番目のinitializeメソッドを使用しようとするとエラーがでます。
これは、一番目のinitializeメソッドの定義が、二番目のinitializeメソッドの定義で上書きされてしまっているからです。
そのため、一番目のinitializeメソッドの定義はもう存在せず、それを使おうとするとエラーとなります。
子クラスから親クラスのinitializeを呼ぶ方法
クラスは、そのデータとメソッドをそのまま引き継いで、子供のクラスを作成できます。
子供のクラスのことを子クラスと言います。
親クラスから子クラスへデータやメソッドを引き継ぐことを継承と言います。
継承した子クラスから親クラスのinitializeメソッドを呼ぶには、superというメソッドを呼びます。
superとは親という意味で、superメソッドが親クラスのinitializeメソッドにつながっています。
# 親クラス class Human def initialize(name) @name = name end end # 子クラス class Woman < Human def initialize(name, bag) super name @bag = bag end def who? puts "She name is " + @name + " having bag of " + @bag end end # 子クラスを作成 w = Woman.new('Kity','Coach') # 子クラスのwho?メソッドを実行 w.who?
実行結果:
She name is Kity having bag of Coach
子クラスで受け取ったnameをsuperに渡して、親クラスのinitializeメソッドを呼び出し、変数@nameを初期化できています。
子クラスのwho?メソッドでも親クラスの@nameを使用できています。
initializeでのreturnとorverrideについて
initializeでのreturn
initializeメソッド内ではreturnは使えません。
以下、実際のコードで確かめてみましょう。
class Singleton def initialize(obj = nil) return obj if obj end end # 一つ目のインスタンス s = Singleton.new # 二つ目のインスタンス。returnで一つ目のインスタンスを返しているハズ s2 = Singleton.new(s) # 両者は同じインスタンス? #=> 違うインスタンス p s === s2 #=>false
実行結果:
false
return したsがs2に入っているはずですが、両者は別のオブジェクトとして判定されていますね。
これは、newの返値はinitializeの返値ではなく、初期化されたオブジェクトであるためです。
initializeの返値は使用されません。
そのためreturnしても返値は使用されません。
initializeでのorverride
initializeメソッドは重複して定義するたびに、最後に定義されたinitializeメソッドが使用されます。
実際にコードで確認してみましょう。
以下のコードではArrayクラスに新たにinitializeメソッドを定義して通常のArrayのinitializeメソッドを上書き(override)しています。
このカスタマイズしたArrayクラスのインスタンス変数は通常の配列としても使用できています。
# Arrayクラスに新たにinitializeクラスを上書きで作成する class Array # 新たなinitialize def initialize(*args) p "Array Initialize Customized" end # 新たなメソッド def custommessage p "custommessage" end end # カスタマイズしたArrayをnewする a = Array.new # カスタマイズしたArrayのcustommessageメソッドを実行 a.custommessage # 通常の配列(Array)としても使える a[0] = 1 p a
実行結果:
"Array Initialize Customized" "custommessage" [1]
以上のように、組み込みクラスArrayであっても、initializeメソッドをoverrideできます。
また、initializeをoverrideしてカスタマイズしたArrayは、通常の配列(Array)としても使用できています。
Rubyを独学で頑張っているけど先が見えない方のために
そんな方、実はいらっしゃるのではないでしょうか?
そんな方であれば、これから先の話は必要ないでしょう。そっとページの閉じるボタンを押しましょう。
しかし、「先が見えない」と心の底では勘付いているそこの奥さん。この先を読み進めて、一緒に課題を深堀りしていきましょう。
なぜ「先が見えない」という不安や悩みを抱えてしまうのか
さて、「一寸先は闇だ・・・」とお悩みを抱えている方に、なぜ独学でRubyを勉強しているにもかかわらず、そのような現状を抱えてしまうのか、一緒に考えていきましょう。
先が見えない現状を踏まえ、課題として考えられるものは以下のどれかに該当するでしょう。
- プログラミングの上達が見えない
- プログラミングを継続できない気がする
- プログラミングスキルを習得した姿がイメージできない
- プログラミングスキルを活かした仕事を獲得するイメージができない
これらのどれかに該当することによって、「なんとなくプログラミング学習をしている」という状態になってしまいます。
これらの要因は、三日坊主になる理論と同じなんですが、「プログラミング学習をしなきゃ」とプログラミング学習を頑張ってしまっている状態になってしまっています。
受験勉強をやった経験のある方なら頭がもげるほどに首を縦に振ってしまう方も多いのですが、「今日も5時間勉強するぞ」や「今日はこの章を終わらすぞ」というように、学習を進めることに意識が行き過ぎてしまうと、ある程度学習を継続した後に「先が見えない・・・」となってしまいます。
未来に光を当て、プログラミング学習を「成果が出るもの」にするために
先ほど、「なぜ先が見えないという悩みや不安を抱えてしまうのか」という疑問に対しての答えを示していきました。
これらの課題というのは、独学をしていれば9割の方がぶつかってしまう壁だそうで、いわば、あるあるの現象なのです。
独学をしていて、「なんか前に進めていないぞ」と感じるのはこのせいなんですね。甘く見がちですが、非常にやっかい。
これがさらにやっかいさを極めているのは、上記に挙げた課題のほとんどが、1人で解決できないものばかりだからです。
実は、これらのほとんどが経験者に助けてもらいながら解決しないと、すぐに違う方向へと流れてしまいます。
そう言い切れるのは、以前の私もそうだったからです。
エンジニアやプログラマー関連のキャリアに詳しい方や現役のエンジニアに相談しながら修正を加え、学習を実践して今があります。
という方もいるでしょう。そういう時にこそ、プログラミングスクールの無料カウンセリングを利用するのです。
という考えに辿りついてしまいますよね。結論から言うと弊社では、そういった強引な営業等を行うことはありませんので、安心して受講できます。
「プログラミング学習の先ある未来」を光で明るく照らすには、弊社の無料カウンセリングがぴったりだと断言できます。それくらい無料カウンセリングに自信を持っているのです。
さらに、無料カウンセリングには以下の3大特典もついてきます!
- 「最短1ヶ月で開発ができる学習方法」電子書籍(非売品)
- 効率的なオリジナル学習カリキュラム
- 未経験の転職(フリーランス)を可能にするキャリアサポート
上記の特典だけでも他のスクールにはないポイントだと自信を持っている無料カウンセリング特典です。
ただプログラミング学習をする毎日から、ワクワクしながらプログラミング学習できる毎日に変える体験を一度でいいのでしてみませんか?
まとめ
今回は、Rubyの classの定義、newメソッド、inistializeメソッドについて学習しました!
学習のポイントを振り返ってみましょう!
- classは定義した後、newメソッドでインスタンス化して使用する。
- newメソッドを実行した際に、initializeメソッドが実行される。
- newメソッドの引数は、そのままinitializeメソッドに渡される。
- initializeメソッドは複数は用意できない。initializeを定義するたびに以前のinitializeが上書きされる。
- superメソッドによって、子クラスから継承元の親クラスのinitializeメソッドを呼び出せる。
- initializeメソッドではreturnできない。
以上の内容を再確認し、ぜひ自分のプログラムに生かし学習を進めてください!