Ruby初学者が混乱してしまいがちな処理として「new」メソッドと「initialize」メソッドの使い方が挙げられます。
本記事では、Ruby初学者の方向けに「new」と「initialize」それぞれのメソッドの役割を解説しながらクラスとインスタンスの違いについてサンプルコードを掲載しながらご紹介していきます。
目次
newメソッドとは
newメソッドについて理解するためには「クラス」と「インスタンス」の役割を認識しておく必要があります。
クラスは設計図と例えられることが多いのですが、クラスを実際に利用するためにはインスタンス化したオブジェクトが必要となります。
そのインスタンス化を行う際に必要となるのが「new」メソッドです。
newメソッドの書き方
実際にnewメソッドを利用してクラスをインスタンス化する方法は下記となります。
インスタンス名 = クラス名.new
newメソッドに引数を与える
上記の基本となるnewメソッドの書き方に加えて、引数を指定したインスタンス化の方法も存在します。
インスタンス名 = クラス名.new(引数1, 引数2, ...)
引数は複数指定することが可能ですが、後述する「initialize」メソッドで定義された数と一致する必要があります。
newメソッドから呼び出されるinitializeメソッド
では「initialize」メソッドはどこで利用されるのかというと、「new」メソッドが実行された際に自動的に呼び出されることになります。
initializeメソッドの書き方
initializeメソッドはクラス内に下記のように記述します。
例えば「Sample」クラスに引数なしの「initialize」メソッドを実装すると下記のようになります。
class Sample def initialize() p "初期化処理" end end sample = Sample.new
サンプルの場合、インスタンス化するたびにコンソールに「初期化処理」の文言が出力されます。
引数有りのinitialize処理
initializeメソッドは引数ありでも作成することが可能です。
class Sample def initialize(str) p str end end sample = Sample.new("引数ありの初期化処理")
initializeのオーバーロードは出来ない
Rubyではinitializeを複数定義することは出来ません。
class Sample def initialize() p "引数なしの初期化処理" end def initialize(str) p str end end sample = Sample.new("引数ありの初期化処理")
ただし下記のように有効な「initialize」メソッドと異なる引数で「new」メソッドを呼び出した場合エラーとなります。
class Sample def initialize() p "引数なしの初期化処理" end def initialize(str) p str end end sample = Sample.new
実行すると下記のようなエラーとなります。
`initialize': wrong number of arguments (given 0, expected 1)
initializeではreturn出来ない
initializeメソッドではreturnを定義して値を返却することは出来ません。
class Sample def initialize() return "返却は出来ない" end end sample = Sample.new p sample
実行した結果が下記です。
#<Sample:0x00007fecdb1a0c78>
エラーとはなりませんが、変数(sample)には返却値として指定した文字列が設定されるわけではなく、あくまでインスタンス化されたオブジェクトが生成されるだけです。
newメソッドを利用したサンプルコード
実際にnewメソッドを利用したいくつかのサンプルコードで具体的な使い方を確認していきましょう。
初期値を設定
まずはnewメソッドに引数を渡し、いくつかの異なるインスタンスを作成するサンプルコードを確認してみましょう。
class Sample def initialize(name) @name = name end def execute() p @name + "さん こんにちは。" end end sample1 = Sample.new("佐藤") sample2 = Sample.new("鈴木") sample3 = Sample.new("山田") sample1.execute sample2.execute sample3.execute
実行結果が下記となります。
"佐藤さん こんにちは。" "鈴木さん こんにちは。" "山田さん こんにちは。"
「initialize」メソッドで初期値を設定することにより、同じ「execute」メソッドを実行した場合でも異なる出力内容でコンソールに表示されています。
@nameの部分はインスタンス変数と呼ばれるもので、各インスタンスで個別に保有する変数のことを指します。
デフォルト値を設定した初期化処理
「initialize」メソッドは2つ以上定義することが出来ないと説明しましたが、デフォルト値を指定することで引数の異なる「new」メソッドを利用することが可能です。
class Sample def initialize(name="ゲスト1", phone="未定義です") @name = name @phone = phone end def execute() p @name + "さん こんにちは。" p "電話番号は" + @phone + "です。" end end sample1 = Sample.new() sample2 = Sample.new("鈴木") sample3 = Sample.new("山田", "090-1234-5678") sample1.execute sample2.execute sample3.execute
実行結果は下記です。
"ゲスト1さん こんにちは。" "電話番号は未定義ですです。" "鈴木さん こんにちは。" "電話番号は未定義ですです。" "山田さん こんにちは。" "電話番号は090-1234-5678です。"
このようにデフォルト値を設定しておくことで、引数が異なる「new」メソッドを呼び出すことが可能となります。
初期化と同時にメソッドを実行
ちなみにインスタンス変数に格納せずに初期化処理実行後、インスタンスに定義したメソッドを呼び出すことも可能です。
class Sample def initialize(name="ゲスト1", phone="未定義です") @name = name @phone = phone end def execute() p @name + "さん こんにちは。" p "電話番号は" + @phone + "です。" end end Sample.new().execute Sample.new("鈴木").execute Sample.new("山田", "090-1234-5678").execute
実行結果が下記です。
"ゲスト1さん こんにちは。" "電話番号は未定義ですです。" "鈴木さん こんにちは。" "電話番号は未定義ですです。" "山田さん こんにちは。" "電話番号は090-1234-5678です。"
ただしこの方法の場合、インスタンス化されているわけではないため再利用することが出来ない点に注意が必要です。
さいごに: Rubyのnewメソッドとinitializeメソッドの違いを把握しよう
本記事では、Rubyにおける「new」メソッドと「initialize」メソッドそれぞれの違いについてご紹介してきました。
結論として「new」メソッドはクラスをインスタンス化するために呼び出すメソッドであり、「new」メソッドが呼び出された際に自動的に実行されるのが初期化処理である「initialize」メソッドとなります。
クラスとインスタンスの関係は、オブジェクト指向のプログラミング言語を扱う上で必須知識ですので、しっかりと理解出来るように学習しておきましょう。
initializeを複数記述してもエラーとはなりませんが、有効な「initialize」メソッドは最後に記述した1つだけです。