Rubyにおけるオブジェクト指向と基本の書き方

Rubyにおけるオブジェクト指向やクラス、インスタンスの生成、クラスの継承に関して理解が難しかったので、アウトプットを兼ねて記事にしてみました。
学び始めて間もないので認識が間違っている場合がありますので、ご了承ください。

1. [クラスの作成](#1-クラスの作成)
2. [メソッドの組み込み](#2-メソッドの組み込み)
3. [オブジェクトのインスタンス化](#3-オブジェクトのインスタンス化)
4. [インスタンス変数とinitializeメソッド](#4-インスタンス変数とinitializeメソッド)
5. [ゲッターメソッド、セッターメソッド](#5-ゲッターメソッドセッターメソッド)
6. [クラスの継承](#6-クラスの継承)
7. [モジュール](#7-モジュール)

# 1. クラスの作成
```ruby
class Person#クラス名

end
```
- クラス名は英大文字から始める(Human)
- クラス名はキャメルケース(PerfectHuman)で記述する

# 2. メソッドの組み込み
```ruby
class Person#クラス名

    def info(weight, height, age, name)#インスタンスメソッド名
        "名前:#{name} 身長:#{height}cm 体重:#{weight}kg 年齢:#{age}歳"#実行したい処理
    end
end
```
- メソッド名はスネークケースで記述する。
- `def インスタンスメソッド名(引数)`で引数を設定できる。

# 3. オブジェクトのインスタンス化
```ruby
class Person#クラス名

    def info(weight, height, age, name)#インスタンスメソッド名
        "名前:#{name} 身長:#{height}cm 体重:#{weight}kg 年齢:#{age}歳"#実行したい処理
    end
end

#Personクラスからインスタンスを生成
ruby_man = Person.new
ohtani = Person.new

#infoメソッドの引数に代入し実行
info_ruby_man = ruby_man.info(65, 171, 28, "流美井三郎")
info_ohtani = ohtani.info(95, 193, 29, "大谷翔平")

puts info_ruby_man <<名前:流美井三郎 身長:171cm 体重:65kg 年齢:28歳
puts info_ohtani <<名前:大谷翔平 身長:193cm 体重:95kg 年齢:29歳
```
- `インスタンス名 = クラス名.new`でインスタンスを生成する

# 4. インスタンス変数とinitializeメソッド
```ruby
class Person#クラス名

# initializeメソッド
    def initialize(weight, height, age, name)
      @weight = weight#@weightインスタンス変数にweightローカル変数を渡す
      @height = height
      @age = age
      @name = name
    end
    def info#インスタンスメソッド名
        "名前:#{@name} 身長:#{@height}cm 体重:#{@weight}kg 年齢:#{@age}歳"#実行したい処理
    end
end

#Personクラスからインスタンスを生成
ruby_man = Person.new(65, 171, 28, "流美井三郎")
ohtani = Person.new(95, 193, 29, "大谷翔平")

puts ruby_man.info
puts ohtani.info
```
initializeメソッドとは、そのクラスからインスタンスが生成される際に必ず1回実行されるメソッド。そのため、initializeメソッドのローカル変数（引数）に、生成したインスタンスのデータ（引数）が代入され、その代入したローカル変数をクラス内の他のメソッドでも使えるように、インスタンス変数に渡している。
しかし、インスタンス変数は同じクラス内でのみアクセスして使える変数。そこで、クラス外からもアクセスできるようにするのが、ゲッターメソッドとセッターメソッドである。

# 5. ゲッターメソッド、セッターメソッド
```ruby
class Person#クラス名
    #ゲッターメソッド、セッターメソッドの実行
    attr_accessor :weight, :height, :age, :name
    # initializeメソッド
    def initialize(weight, height, age, name)
      @weight = weight#@weightインスタンス変数にweightローカル変数を渡す
      @height = height
      @age = age
      @name = name
    end
    def info#インスタンスメソッド名
        "名前:#{@name} 身長:#{@height}cm 体重:#{@weight}kg 年齢:#{@age}歳"#実行したい処理
    end
end

#Personクラスからインスタンスを生成
ruby_man = Person.new(65, 171, 28, "流美井三郎")
ohtani = Person.new(95, 193, 29, "大谷翔平")

puts ruby_man.info
puts ohtani.info
```
`attr_accessor :weight, :height, :age, :name`と記載することで、インスタンス変数をクラス外部から書き換えたり、読み取ったりすることができる。
※ゲッターメソッド、セッターメソッドに関する詳しい記載は省略します。以下の記事がわかりやすくまとめてあったので貼っておきます。
>https://pikawaka.com/ruby/attr_accessor

# 6. クラスの継承
```ruby
 # クラスの作成
  class Person
    #ゲッターメソッド、セッターメソッドの実行
    attr_accessor :weight, :height, :age, :name
  
    # initializeメソッドの実行
    def initialize(weight, height, age, name)
      @weight = weight
      @height = height
      @age = age
      @name = name
    end
  
    # メソッドの組み込み
    def info
      "名前:#{@name} 身長:#{@height}cm 体重:#{@weight}kg 年齢:#{@age}歳"
    end
  end
  
  # クラスの継承
  class Employee < Person

    def bmi
        "#{@name}のBMIは#{(@weight / ((@height / 100.0) ** 2)).round(1)}です"
    end
  end

  class Athlete < Person
  
    def basic_metabolism_rate
      "#{@name}の基礎消費kcalは#{(66.47 + @weight * 13.75 + @height * 5.0 - @age * 6.76).round}kcalです"
    end
  end
  
  # 各クラスからインスタンスの生成
  ruby_man = Employee.new(65, 171, 28, "流美井三郎")
  ohtani = Athlete.new(95, 193, 29, "大谷翔平")
  
  # メソッドの実行と一括で出力
  puts ruby_man.info#<<名前:流美井三郎 身長:171cm 体重:65kg 年齢:28歳
  puts ruby_man.bmi#<<流美井三郎のBMIは22.2です
  puts ohtani.info#<<名前:大谷翔平 身長:193cm 体重:95kg 年齢:29歳
  puts ohtani.basic_metabolism_rate#<<大谷翔平の基礎消費kcalは2142kcalです
```
クラスの継承とは、親クラスで定義されたメソッドやオブジェクトを引き継ぎ、子クラスに反映させることができる仕組み。上記のサンプルコードでは、`Person`クラスという親クラスから、`Employee`クラスと`Athlete`クラスという子クラスに`initialize`メソッドや`info`メソッドが引き継がれているため、子クラスに改めて記載する必要がなくなっている。

# 7. モジュール
```ruby
# モジュールの作成
module Wage
    def daily_wage(salary)
      "#{name}の日給は#{(salary / 260.0).round(1)}万円です"
    end
  end
  
  # クラスの作成
  class Person
    include Wage#モジュールの組み込み
    attr_accessor :weight, :height, :age, :name
  
    # initializeメソッドの実行
    def initialize(weight, height, age, name)
      @weight = weight
      @height = height
      @age = age
      @name = name
    end
  
    # メソッドの組み込み
    def info
      "名前:#{@name} 身長:#{@height}cm 体重:#{@weight}kg 年齢:#{@age}歳"
    end
  end
  
  # クラスの継承
  class Employee < Person
    include Wage#モジュールの組み込み

    def bmi
        "#{@name}のBMIは#{(@weight / ((@height / 100.0) ** 2)).round(1)}です"
    end
  end

  class Athlete < Person
    include Wage

    def basic_metabolism_rate
      "#{@name}の基礎消費kcalは#{(66.47 + @weight * 13.75 + @height * 5.0 - @age * 6.76).round}kcalです"
    end
  end
  
  # 各クラスからインスタンスの生成
  ruby_man = Employee.new(65, 171, 28, "流美井三郎")
  ohtani = Athlete.new(95, 193, 29, "大谷翔平")
  
  # メソッドの実行と一括で出力
  puts ruby_man.info#<<名前:流美井三郎 身長:171cm 体重:65kg 年齢:28歳
  puts ruby_man.bmi#流美井三郎のBMIは22.2です
  puts ruby_man.daily_wage(400)#流美井三郎の日給は1.5万円です

  puts ohtani.info#名前:大谷翔平 身長:193cm 体重:95kg 年齢:29歳
  puts ohtani.basic_metabolism_rate#大谷翔平の基礎消費kcalは2142kcalです
  puts ohtani.daily_wage(1000000)#大谷翔平の日給は3846.2万円です
```
モジュールのイメージは制限のあるクラスのようなもの。モジュールからインスタンスを生成することや継承はできないが、クラスの継承のようにモジュール内で定義したメソッドなどを他のクラスに組み込むことで定義した処理を使うことができる。比較的頻繁に使う処理などをモジュールにまとめて定義することでクラスでコードを書く手間が省ける。

# 最後に
現時点での自分の理解できた部分を実際に簡単なコードを書きながらまとめてみました。何かご指摘やアドバイスなどありましたらコメントいただけると幸いです。
なお、本記事に登場する人物やデータは全てフィクションです。