オブジェクト指向におけるクラスの概念（Ruby）

## クラスとインスタンス
　クラスは、**インスタンスを作成する時に「元となる設計図」**のことで、インスタンスは、**設計図をもとに作成される実物体**のことをいいます。

|用語|役割|例1|例2|
|:--:|:--:|:--:|:--:|
|クラス|設計図|車の設計図|たい焼きの型|
|インスタンス|設計図をもとに作成される実物体|黒い車、赤い車|クリームのたい焼き、あんこのたい焼き|
　Rubyは、**「もの」を組み立てるように表現してコンピュータに指示するオブジェクト指向プログラミング言語**です。「もの」を組み立てる際の設計図が**「クラス」**で、その設計図から作成された実物体のことを**「インスタンス」**と呼びます。

## オブジェクト指向プログラミング言語
　プログラミングとは、コンピュータが理解できる言葉を並べてプログラムを作ることです。その際に、**プログラムの意図したことを順番通りにコンピュータに動作させる指示**を出しています。
　プログラムの意図したことを順番通りに表現する代表的な方法は以下の通りです。

|プログラムの表現方法|プログラムの流れ|
|:--:|:--:|
|オブジェクト指向プログラミング|**「もの」を組み立てる様に表現してコンピュータに指示する**|
|手続き型プログラミング|プログラムを上から順番に処理を実行する|
|関数型プログラミング|関数の組み合わせによってプログラムを組み立てる様に表現する|
　このプログラムの表現方法の中で、**Rubyは、オブジェクト指向プログラミング言語**です。
　物を組み立てコンピュータを動作させるために、物の設計図であるクラスと物の実物体であるオブジェクトが必要です。

### ポイント
①Rubyはオブジェクト指向プログラミング言語です。
②オブジェクト指向とは、「もの」を組み立てるように表現してコンピュータに指示するプログラムの表現方法
③物を組み立てプログラムを表現するために、物の設計図であるクラスと**設計図から作成される**実物体のインスタンスが必要です。

## メソッドの特徴を理解しよう
　メソッドとは、**複数の処理を1つにまとめて、扱いやすくしたもの**です。
　メソッドの基本的な書き方は、以下の通りになリます。

```ruby
def メソッド名
  # 処理
end

# メソッド実行
メソッド名
```
　例）helloメソッドを定義して実行する

```ruby
def hello
  puts "hello!"
end

# helloメソッド実行
hello
# => hello!
```
### メソッドの特徴
　メソッドは下記のような特徴があります。
①メソッドに値を渡すことができる
②メソッド内で最後に評価される値を返す

```ruby
def hello(name)
  puts "#{name},hello!" → ここがメソッド内で最後に評価されている
end

# helloメソッド実行
hello("kaito")
# => kaito,hello!
```
③メソッド内で定義した変数は、**外部からアクセスすることができない**

```ruby
# メソッド内に変数を追加
def hello
  other_name = kaito
  puts "hello!"
end

# メソッド内の変数のather_nameをメソッド外から指定するとエラーが出る
puts other_name
# => NameError: undefind localvariable or method 'other_name' for main:object
```
## クラスの作り方
　「たい焼きのイメージ」と「メソッドの特徴」を踏まえた上でクラスを作成します。

### クラス作成
　クラスの定義は、以下のように記述します。

```ruby
class クラス名
  # メソッドなど
end
```
　ここで重要なのは、メソッドの時と違い**クラス名の最初の文字が大文字**ということです。

```ruby
class Taiyaki

  def メソッド
  end

end
```
### インスタンス作成
　インスタンスは、以下のようにクラスから作成します。

```ruby
クラス名.new
```
　たい焼きの型からたい焼きを作り出すには、以下のように記述します。

```ruby
class Taiyaki

  def メソッド
  end

end

# たい焼きの設計図からたい焼きを作成
taiyaki = Taiyaki.new
# => <Taiyaki:0x00~>
```
　Taiyaki.newの返り値が、「<Taiyaki:0x00~>」なので、たい焼きのインスタンス（オブジェクト）が作成されたことがわかります。

### initializeメソッドとインスタンス変数
　たい焼きを作ることができましたが、このままではたい焼きの味（taste）や値段（price）がわかりません。たい焼きに情報を持たせるためにインスタンス作成時に、たい焼きの情報を引数に渡します。

|渡したいたい焼きの情報|インスタンス作成|
|:--:|:--:|
|あんこ味のたい焼き　250円|Taiyaki.new（"あんこ", 250）|
|カスタード味のたい焼き　300円|Taiyaki.new("カスタード", 300)|
|抹茶味のたい焼き　330円|Taiyaki.new("抹茶", 330)|
　引数で渡された値は、**「インスタンス作成時」に実行されるinitializeメソッド**を利用して**「@のついたインスタンス変数」**に代入します。

```ruby
class Taiyaki

  # インスタンス作成の時に実行される
  def initialize(taste, price)
    # インスタンス変数には@をつける
    @taste = taste
    @price = price
  end

end

# newした際にinitializeメソッドが実行され、引数の値がインスタンス変数に代入される
anko_taiyaki = Taiyaki.new("あんこ", 250)
# => <Taiyaki:0x00~ @taste = "あんこ", @price = 250>
```
　インスタンスを作成するときに、initializeメソッド内でインスタンス変数に引数で渡した値を代入させることによって、**インスタンス変数は、インスタンスごとに値を保持することができます。**
　たい焼きを作りときは、それぞれのたい焼きごとに味や値段を変えることができます。

|インスタンス作成|インスタンス変数の値の中身|
|:--:|:--:|
|Taiyaki.new("あんこ", 250)|@taste="あんこ", @price=250|
|Taiyaki.new("カスタード", 300)|@taste="カスタード", @price=300|
|Taiyaki.new("抹茶", 330)|@taste="抹茶", @price=330|
　メソッドの特徴として、**メソッドの内で定義した変数はメソッドの外では利用できませんでしたが**、インスタンス変数はインスタンス内であればどこでも呼び出すことができます。

### インスタンスメソッド
　インスタンスメソッドとは、**作成したインスタンスから実行できるメソッド**のことです。
　先ほと作成したanko_taiyakiのインスタンスは、initizlizeメソッドでインスタンス変数に「@taste="あんこ", @price=250」を代入したため、この情報を保持してます。

　インスタンスメソッドは、このインスタンスごとに保持している情報を使って処理を書くことができます。

```ruby
# たい焼きの設計図を作成
class Taiyaki

  # インスタンス作成時に実行される
  def initialize(taste, price)
    @taste = taste
    @price = price
  end

  # 作成したインスタンスから実行できるインスタンスメソッド
  # インスタンスによって、@taste,@priceの値が異なる
  def show_info
    puts "#{@taste}味のたい焼きは#{@price}円です。"
  end

end

# anko_taiyakiのインスタンス作成
anko_taiyaki = Taiyaki.new("あんこ", 250)
# => <Taiyaki:0x00~ @taste="あんこ", @price=250>

# 作成したanko_taiyakiのインスタンスからshow_infoインスタンスメソッドを実行する
anko_taiyaki.show_info
# => あんこ味のたい焼きは250円です。
```
　show_infoインスタンスメソッドは、作成したインスタンスによって文章の内容が異なります。これは**インスタンスごとに保持するデータを変えることができるからです。**
　試しにカスタード味のたい焼きを作って確認します。

```ruby
custard_taiyaki = Taiyaki.new("カスタード", 300)
# <Taiyaki:0x00~ @taste="カスタード", @price=300>

custard_taiyaki.show_info
# カスタード味のたい焼きは300円です。
```

### クラスメソッドの定義
　先程のインスタンスメソッドは、インスタンスから呼び出すことができましたが、その他にも**クラスから呼び出すことができるクラスメソッド**があります。
　クラスメソッドとは、**インスタンスに依存せずにクラス全体に紐付けられるメソッドのこと**です。インスタンスの持つデータを使う必要のない処理は、クラスメソッドで定義します。
　クラスメソッドは、2つの定義方法があります。

```ruby
# クラスメソッドの定義方法1
class クラス名
  def self.クラスメソッド名
  end
end

# クラスメソッドの定義方法2
class クラス名
  # この中で定義するとクラスメソッドと認識されます。
  class << self
    # メソッド名にselfは必要ない
    def test
    end
  end
end
```
　クラスメソッドは、以下のように呼び出すことができます。

```ruby
クラス名.クラスメソッド名
```

### クラス変数
　インスタンス変数の他に、**クラス変数という@が2つ付く変数**があります。
　インスタンス変数が作成された各インスタンスごとに共有される変数だったのに対して、**クラス変数は、全てのインスタンスで共有される変数です。**
　たい焼きが全部で何個作成されたかわかるクラス変数「@@total_taiyaki_count」と、それを案内するクラスメソッドを定義します。

```ruby
# たい焼きの設計図を作成
class Taiyaki

  # 全てのインスタンスで共有されるクラス変数
  @@total_taiyaki_count = 0

  # インスタンス作成時に実行される
  def initialize(taste, price)
    @taste = taste
    @price = price

    # インスタンスが作成（new）される毎にカウントアップ
    @total_taiyaki_count += 1
  end

  # インスタンスメソッド
  def show_info
    puts "#{taste}味のたい焼きは#{price}円です。"
  end

  # クラスメソッド
  def self.shoe_all_count
    puts "たい焼きは全部で#{@@total_taiyaki_count}個作成されました。"
  end

end
```
　クラス変数「@@total_taiyaki_count」によってTaiyakiクラスからインスタンスを作成する度に1ずつ増える為、たい焼きの作成した個数を知ることができます。

```ruby
# anko_taiyakiのインスタンスを作成（カウントアップされる）
anko_taiyaki = Taiyaki.new("あんこ", 250)
# => <Taiyaki:0x00~ @taste="あんこ", @price=250>

# custard_taiyakiのインスタンスを作成（カウントアップされる）
custard_taiyaki = Taiyaki.new("カスタード", 300)
# => <Taiyaki:0x00~ @taste="カスタード", @price=300>

# たい焼きの個数を調べるためにshow_all_countクラスメソッドを実行する
Taiyaki.show_all_count
# => たい焼きは全部で2個作成されました。
```

## 終わりに
　今回は、クラスについて学習しました。railsを用いてポートフォリオサイトを作成することはできましたが、rubyの基礎知識の部分を忘れていることが多く面接の時に苦労したため、今後は基礎知識の部分を重点的に学習していきます。