🤖

Rubyの世界へようこそ ~クラスとは?~

2024/01/21に公開

Ruby クラスの書き方と使い方

「クラス」とは?

クラスとは、インスタンス(オブジェクト)の設計図にあたるものです。

クラスの中には、ある機能を実現するために必要な「変数」や「関数」がひとまとまりになっています。

ひとまとめにしてテンプレート化しておくことで、後から再利用がしやすいというメリットがあります。

また、開発の手間が省けるだけではなく、処理手順が漏れてしまうようなミスも防ぐことができます。

「インスタンス」とは?

インスタンスとは、クラスを基に生成される実体のことです。

クラスという「金型」を使って、実際の製品を複製するようなイメージです。

クラスの書き方

クラス内に、関連するデータやメソッドをまとめることで、コードをより効果的に構造化することができます。

クラスの書き方
ruby.rb
# クラスの定義
class クラス名
  def インスタンスメソッド名
    実行したい処理
  end
end

# インスタンスの生成
変数名 = クラス名.new()

# 生成したインスタンスで、インスタンスメソッドを実行
変数名.インスタンスメソッド名

「クラス名」は、「メソッド名」と区別するために、以下のような命名規則があります

  • クラス名は英文字の大文字で始める
  • 2種類以上の単語がつながる場合は、キャメルケースにする(各単語の先頭を大文字にする)

クラスの使い方①

では、実際に「自己紹介ロボット」を作って、クラスやインスタンスの使い方を見ていきましょう。

クラスの使い方①
ruby.rb
# クラスの定義
class Robot
  def info(name, birth, type)
    "私の名前は、#{name}です。#{birth}年製の#{type}型ロボットです。"
  end
end

# インスタンスの生成
robot = Robot.new()

# インスタンスメソッドの実行
robot.info("寅衛門", 2112, "トラ")
  • Robotクラスが定義されています。このクラスには infoというメソッドが含まれています。このメソッドは3つの引数(name、birth、type)を取り、それらを使って文字列を生成しています。

  • Robot.new()を使用して Robotクラスの新しいインスタンスrobotを生成しています。

これをターミナルに出力してみると、以下のような実行結果が返ってきます。

# 実行結果の出力
puts robot.info("寅衛門", 2112, "トラ")

# 出力結果
私の名前は、寅衛門です。2112年製のトラ型ロボットです。

クラスの使い方② ~initializeメソッド~

initializeメソッドは、クラスのインスタンスを生成する際の「初期化」メソッドとも言われています。

initializeメソッドを定義しておくと、インスタンスの生成時に必ず実行したい処理を、メソッドを呼び出すことなく実行することができます。

つまり、上の「クラスの使い方①」で言うと、

  • robot.initialize()  ← このように書いていなくても、
  • robot = Robot.new() ← こう書いた時点で実行されるメソッドです。

これを利用して、先ほどの「自己紹介ロボット」のコードを書き直してみましょう。

クラスの使い方②
ruby.rb
# クラスの定義
class Robot
  def initialize(name, birth, type)
    @name = name
    @birth = birth
    @type = type
  end

  def info
    "私の名前は、#{@name}です。#{@birth}年製の#{@type}型ロボットです。"
  end
end

# インスタンスの生成
robot = Robot.new("寅衛門", 2112, "トラ")

# インスタンスメソッドの実行
robot.info
# 実行結果の出力
puts robot.info

# 出力結果
私の名前は、寅衛門です。2112年製のトラ型ロボットです。

先ほどと同じ実行結果を出力することができました。では、どこが変わったのかを確認していきましょう。

  • Robotクラスのインスタンスが生成されると、必ずinitializeメソッドが実行されるので、

    • initializeメソッドの引数に(name, birth, type)をもたせます。
    • Robot.newの引数に("寅衛門", 2112, "トラ")をもたせます。
    • これにより、initialize(name = "寅衛門", birth = 2112, type = "トラ")として処理することができます。
  • initializeメソッド内の変数を、同じクラス内であればどこでも使える変数(インスタンス変数)にしたいので、

    • @name = name
    • @birth = birth
    • @type = type
      と代入します。
  • infoメソッド内の#{変数名}だった場所も、#{@インスタンス変数名}に書き換えることで、infoメソッドからでもinitializeメソッド内の@インスタンス変数名を参照することができます。

クラスの使い方③ ~クラスの継承~

すでに定義されているクラスを拡張して、新しいクラスを作ることを「継承」と言います。

クラスの使い方③
ruby.rb
# クラスの定義
class Robot
  def initialize(name, birth, type)
    @name = name
    @birth = birth
    @type = type
  end

  def info
    "私の名前は、#{@name}です。#{@birth}年製の#{@type}型ロボットです。"
  end
end

# クラスの継承
class LatestModelRobot < Robot 
                                ← このクラス内に、メソッドなどを書いていません。
end     

# インスタンスの生成
latest_model_robot = LatestModelRobot.new("寅衛門", 2112, "トラ")

# インスタンスメソッドの実行
latest_model_robot.info
# 実行結果の出力
puts latest_model_robot.info

# 出力結果
私の名前は、寅衛門です。2112年製のトラ型ロボットです。
  • LatestModelRobotクラスの中に特に何もメソッドなどを書いていないのに実行結果が得られるのは、親クラスであるRobotクラスのメソッドをLatestModelRobotクラス側から呼び出すことができるからです。

クラスの使い方④ ~オーバーライド~

子クラス内で、継承したメソッドをアレンジしたい場合、以下のように上書きすることができます。

クラスの使い方④
ruby.rb
# クラスの定義
class Robot
  def initialize(name, birth, type)
    @name = name
    @birth = birth
    @type = type
  end

  def info
    "私の名前は、#{@name}です。#{@birth}年製の#{@type}型ロボットです。"
  end
end

# クラスの継承
class LatestModelRobot < Robot 

  def info
    "私の名前は#{@name}です。#{@birth}年製の#{@type}型ロボットの中で、最新型のモデルです"
  end
end     

# インスタンスの生成
latest_model_robot = LatestModelRobot.new("寅衛門", 2112, "トラ")

# インスタンスメソッドの実行
latest_model_robot.info
# 実行結果の出力
puts latest_model_robot.info

# 出力結果
私の名前は、寅衛門です。2112年製のトラ型ロボットの中で、最新型のモデルです。
  • LatestModelRobotクラス内に、Robotクラスと同じinfoメソッドが定義されたことで、親クラス内のメソッドを子クラス側で上書きして使用することができます。
  • このように、親クラスから引き継いだメソッドを子クラスで再定義することを、「オーバーライド」と言います。

では、この状態で親クラスのinfoメソッドにはどのような影響があるのかをみてみましょう。

ruby.rb
# クラスの定義
class Robot
  def initialize(name, birth, type)
    @name = name
    @birth = birth
    @type = type
  end

  def info
    "私の名前は、#{@name}です。#{@birth}年製の#{@type}型ロボットです。"
  end
end

# クラスの継承
class LatestModelRobot < Robot 

  def info
    "私の名前は#{@name}です。#{@birth}年製の#{@type}型ロボットの中で、最新型のモデルです"
  end
end     

# インスタンスの生成
robot = Robot.new("寅衛門", 2112, "トラ")
latest_model_robot = LatestModelRobot.new("寅衛門", 2112, "トラ")

# インスタンスメソッドの実行
robot.info
latest_model_robot.info
# 実行結果の出力
puts robot.info
puts latest_model_robot.info

# 出力結果
私の名前は、寅衛門です。2112年製のトラ型ロボットです。
私の名前は、寅衛門です。2112年製のトラ型ロボットの中で、最新型のモデルです。

このように、子クラス内でオーバーライドしてあるとしても、親クラス自体には影響がないことが分かります。

まとめ

クラスはオブジェクト指向プログラミングにおいて重要な概念であり、クラスを使いこなすことで、コードの可読性・再利用性・保守性が向上し、柔軟で拡張可能なソフトウェアの開発が可能となります。

1ヶ月前に学習した内容の復習として、このブログにまとめました。初見ではつかみ切れなかった部分だったので、今回自分なりにまとめることで、理解につなげることができました。

皆さんも、ぜひ「クラス」について調べて、活用してみてください!

参考

https://www.youtube.com/watch?v=FRiF6XLRpSE

Discussion