オブジェクト指向プログラミングとは何か？を整理してまとめた

##記事作成の経緯
オブジェクト指向プログラミングについて徹底的に調べました。
多くの記事や書籍を読み込んだところ、

**「実践していくうえでわかってくるよ」**

ここが結論になる記事が多かったです。
たしかに、オブジェクト指向プログラミングは、効率よく開発するための考え方（概念）なので、文章だけで理解するのは難しいですし、実務経歴10数年のベテランエンジニアでも答えがバラけることがあるそうです。

しかし、実務経験のない初学者が、"なんとなくの理解"だけで実務レベルの実装ができるとは思いません。
実際、私はインターンを経験し、オブジェクトのデータや振る舞い、データ型、継承などを正しく理解していないと、**まともな実装はできない**なと感じました。

そこで今回、もう一度オブジェクト指向プログラミングについて、徹底的に調べたのです。

##対象者
* オブジェクト指向プログラミングを"なんとなく"わかっている初学者
* 少し実務を経験し、自分の実力のなさに打ちのめされた人（私です）

##目次

* オブジェクト指向とは
* オブジェクト指向の基本用語
 * オブジェクト
 * クラス
 * 継承
 * カプセル化
 * ポリモーフィズム
* オブジェクト指向のメリット
* オブジェクト指向のデメリット
* オブジェクト指向の主なプログラミング言語
* 代表的なプログラムを表現する手法
* まとめ

##オブジェクト指向とは
**オブジェクト指向とは、いかに効率よく開発していくのかを突き詰めた考え方です。**
他にもいろいろな言い回しがあると思いますが、一言でいうとこうなります。

##オブジェクト指向の基本用語
今回の解説を理解するうえで、覚えておいてほしい基本用語を紹介します。
「理解しているよー」という人は読み飛ばしていただいてかまいません。

* オブジェクト
* クラス
* 継承
* カプセル化
* ポリモーフィズム（多態性）

それでは順番に解説していきます。

###オブジェクト
そもそもオブジェクトとはなんでしょうか。
**オブジェクトとは、データと、そのデータに対する処理をひとまとめにしたものです。**

実はこのオブジェクト、さまざまな呼び方をもっています。

* インスタンス
* レシーバ

上記２つもオブジェクトと同じ意味で使用されます。
例えば、「Userクラスのインスタンス」と「Userクラスのオブジェクト」は、同じ意味です。

###クラス
クラスとは、オブジェクトを作成するための設計図のことです。
よく「たい焼きの型」をクラス、「たい焼き」をオブジェクトに例えることがありますよね。
つまり、設計図（クラス）をもとに、オブジェクト（データや処理）が作成されます。

```ruby:user.rb
class User
 #=>この中にデータやメソッドを定義できる。
end
```

Rubyでは、このようにクラスを定義します。
クラスを定義することで、データやメソッドの整理がしやすくなります。

##継承
**継承とは、特定のオブジェクトの機能を引き継いで使うことです。**
似たようなオブジェクトを作成するさい、何度もデータやメソッドを作成する手間を省きます。

```ruby:users_controller.rb
class UsersController < ApplicationController #=> ApplicationControllerを継承している
 def index
   @users = User.all
 end

 def show
   @user = User.find(params[:id])
 end
end
```

Railsでよく見るこの形ですが、これは``ApplicationController``を継承しています。
``ApplicationController``が持つデータやメソッドの構造を``UsersController``でも使用できるのです。

上位クラスをスーパークラス、下位クラスをサブクラスと呼びます。

##カプセル化
**カプセル化とは、データとメソッドをひとまとめにし、範囲を明確にすることです。**
言葉のとおり、データやメソッドをカプセルにまとめるイメージをすると、理解しやすいです。

カプセル化するメリットは、プログラムが壊れにくく、情報を隠すことができます（情報隠蔽）。
開発者がカプセルの中身をすべて知る必要がないので、効率的に開発を進められます。

また、他のオブジェクトが直接データにアクセスすることは、基本的にはできません。
オブジェクトのデータにアクセスするには、メッセージという形でオブジェクトに送る必要があります。

メッセージとは、メソッドと同じ意味です。
下記の例は、情報を隠蔽している例になります。

```ruby:user.rb
class User
  def initialize(first_name = "Tarou", name = "Tanaka")
    @first_name = first_name
    @name = name
  end
end

user_name = User.new
user_name.name #<=nameメソッドはUserクラスで定義されていない。
#=> test.rb:9:in `<main>': undefined method `name' for #<User:0x00007fe914041708 @first_name="Tarou", @name="Tanaka"> (NoMethodError)
```

クラスの中にあるインスタンス変数(``@first_nameや@name``)の値を参照するためのメソッドが定義されていないためエラーが起きています。

次に、``attr_accessor``を使用し、メソッドを定義してみます。

```ruby:user.rb
class User
  attr_accessor :first_name, :name

  def initialize(first_name = "Tarou", name = "Tanaka")
    @first_name = first_name
    @name = name
  end
end

user_name = User.new
p user_name.name
p user_name.first_name
#=> "Tanaka"
#=> "Tarou"
```

このように``attr_accessor ``を使うことで、メソッドが定義され、インスタンス変数(``@first_nameや@name``)のデータを参照できました。

ちなみに、``attr_accessor ``は内部で次のような処理をおこなっています。

*(1)引数のシンボルすべてに対して以下の処理を繰り返す。
(2)シンボルで指定された名前のメソッドを定義する。そのメソッドはシンボルの名前の先頭に「@」を付加したインスタンス変数の値を取り出す。(ゲッター)
(3)シンボルで指定されたメソッド名の後ろに「=」を付加した名前のメソッドを定義する。そのメソッドは引数を1つ取り、その値をシンボルの名前の先頭に「@」を付加したインスタンス変数に設定する。（セッター）
[rubyオブジェクト指向（８）カプセル化から引用](https://note.com/taka027/n/nbc4ff8856ef8)*

"知りたいことだけを表に出す"ことがカプセル化の特徴です。

###ポリモーフィズム(多態性)
**ポリモーフィズムとは、さまざまなオブジェクトに対して、同じメソッドを呼び出しても、出力される結果が異なることです。**
例えば、「グー」「チョキ」「パー」というオブジェクトがあるとして、"Go"というメソッドを呼び出すと、それぞれ「グー」「チョキ」「パー」という異なる結果を出力します。
つまり、同じ"Go"というメソッドを呼び出しても、オブジェクトごとに出力結果は異なるよ。ということです。

##オブジェクト指向のメリット・デメリット
ここまで、オブジェクト指向プログラミングの概要と基本用語について解説してきました。
ここまでの解説で「点の知識が線になった」人もいると思います。

現在、多くのプログラミング言語がオブジェクト指向を採用しています。
ここではオブジェクト指向のメリット・デメリットを見ていきましょう。

###オブジェクト指向のメリット
オブジェクト指向のメリットは以下のとおりです。

1. プログラムの全体像を把握しやすい
2. 分業や共同作業しやすい
3. 改良や修正がしやすい
4. 計算を高速化でき、メモリを軽量化できる

###オブジェクト指向のデメリット

1. 理解しづらい
2. 大人数で開発する場合、理解度により作業の停滞を産み出す
3. 一から開発する場合、コードが複雑になりやすい

やはり概念を理解するというのは簡単ではありません。
「愛と何か？」とか「幸せとはどうあるべきか」のような抽象度の高い概念を説明しようとすると、答えにバラつきがでるのは当然ですよね。

##オブジェクト指向を採用した主なプログラミング言語
- C++
- Python
- Java
- Ruby
- PHP
- JavaScript

##代表的なプログラムを表現する手法
- オブジェクト指向プログラミング
- 手続き型プログラミング
- 関数型プログラミング

##まとめ

**オブジェクト指向とは、オブジェクト指向とは、いかに効率よく開発していくのかを突き詰めた考え方である**
とりあえずこれだけは覚えておきましょう。面接などで聞かれたときにさっと答えられるといいですね。

オブジェクト指向プログラミングを本気で解説しようとしたら、とてもこれだけでは解説しきれません。
この記事では、オブジェクト指向プログラミングの概要理解に徹底しました。
まだまだ学習中なので、もっといい表現や、わかりやすい言い回し、イメージしやすい図があればどんどん更新していきます。

##参考文献
[キタミ式イラストIT塾　基本情報技術者](https://www.amazon.co.jp/dp/B082DT76Z8/ref=cm_sw_em_r_mt_dp_BZ2G6KT0HZ5W8HHBE50C)
[オブジェクト指向設計実践ガイド](https://www.amazon.co.jp/dp/B01L8SEVYI/ref=cm_sw_em_r_mt_dp_FXHSKPJ28J0VXHQXZEDV)
[プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで](https://www.amazon.co.jp/dp/B077Q8BXHC/ref=cm_sw_em_r_mt_dp_GPDPGTQ0G1K2NT2YSHTT)