関連記事
オブジェクト指向とは?
この記事の動画版はこちら(画像クリックでYoutubeに飛びます)
オブジェクト指向とは?
結論から先に言うと、
オブジェクト指向とは、一連の処理に使う「変数」や「関数」をひとまとめにして、再利用できるように名前をつけてテンプレ化しておこう!という考え方です。
オブジェクト指向はなぜ必要?
オブジェクト指向を理解するために、まずは「そもそもなぜオブジェクト指向が必要なのか?」ということを知っておきましょう。
細かい技術的な話よりも、まずその根底にある「本質」を知ることが大事です。
これは人によって色々な考え方があると思いますが、僕が考えるオブジェクト指向が必要な理由
それは「面倒くさいから」です。
プログラマーは基本「面倒くさがり」です。
一度書いた処理は、できればもう金輪際書きたくない。
しかし、プログラムを作っていると、同じような処理を何度も書かなければならないことがよくあります。
同じ処理を何度も書くのはとても面倒くさい。
だったらその処理を「テンプレ化」して再利用できるようにしてしまおう!
これが、オブジェクト指向の根底にある考え方です。
オブジェクト指向という方法でプログラムを書くことで、一度書いたプログラムをテンプレ化しておくことができ、それを再利用することで、次はより少ないコードで実現できるというメリットがあります。
ただ、逆にオブジェクト指向を全く使わなくても、アプリを作ることは可能です。
つまり、オブジェクト指向は「使わなくても別に問題はないけど、使えばより便利になる技術」という訳ですね。
関数とは何が違う?
ここまで聞くと、「じゃあ関数とは何が違うの?」と思うかもしれません。
関数とは、再利用できそうな処理を関数として定義しておくことで、次からはその関数を呼び出すだけで、処理を行ってくれる便利な仕組みです。
詳しくは、こちらの記事で説明しているのでチェックしてみてください。
しかし、関数はあくまで決められた1つの処理を行ってくれるものでしかありません。
実際のプログラムでは、1つの処理だけでなく、色々なデータを準備したり、いくつもの処理手順を行うことがあり、それら一連の処理セットが色々な場所で再利用されるような場合もあります。
例えば、メール送信処理。
単純なメール送信なら、関数を1つ呼び出すだけで良いんですが、HTMLメールの送信やファイルの添付といった、より高度なメール送信処理を行おうとすると、データの準備や、内容のチェック、ヘッダー情報やボディ情報の設定、送信処理、送信後のチェック処理など、様々な処理手順が必要になります。
そして、メール送信処理はアプリの色々な場所で行われるので、これら一連の処理を毎回毎回書くのは面倒です。
そこで、一連の処理に使う「変数」や「関数」群をひとまとめにしてテンプレ化しておこうと考えます。
処理に必要な変数や関数を煩雑に管理するのではなく、ある「役割」を行う「物(=オブジェクト)」として、名前を付けて定義しておこう。
この場合は「メール送信を行うオブジェクト」として定義しておこう。
そうすれば再利用もしやすいよね!というプログラミング手法。
これが「オブジェクト指向」です。
一連の処理に使う「変数」や「関数」をひとまとめにして、再利用できるように名前をつけてテンプレ化しておこう。
という考え方ですね。
クラスとインスタンス
そして、この定義されたテンプレのことを「クラス」と言います。
クラスには、この処理に必要な「データ(変数)群」と「処理(関数)群」が含まれます。
クラスの中では、それぞれ「プロパティ」と「メソッド」と呼ばれます。
なお、クラスはあくまで「テンプレート」です。
実際にメールを送る際は、メールの宛先や、件名、本文などは毎回異なるので、このテンプレを元にして、実際のデータをセットしたものを作成する形になります。
これを「インスタンス」といいます。
金型(クラス)を元に、製品(インスタンス)を作るようなイメージですね。
クラスは「金型」、実際に使う際は金型から「インスタンス」を生成する、と覚えておきましょう!
オブジェクト指向のメリット
このように、オブジェクト指向では、
単純な関数とは異なり、必要な「データ」や「処理」をひとまとめにして管理できるというメリットがあります。
オブジェクトとして、ひとまとめに管理されているため、このオブジェクト自体を変数として丸ごと持ち運んだりといった扱い方もできます。
さらに、オブジェクト指向には「3つのメリット」があります。
それが
という機能です。
◆継承(クラスを継承できる)
継承とは「能力を引き継ぐこと」です。
あるクラスの能力を引き継いだ、別のクラスを作ることができます。
例えば、先ほどのMailクラスには基本的なメール送信の処理が実装されていますが、絵文字を送る機能が無かったので、絵文字を送ることができる新しいメール送信クラスを作りたいと思ったとします。
クラス名は「EmojiMail」クラスにしましょう。
その場合、新しく作る「EmojiMail」クラスに、先ほどMailクラスに書いた様々な処理をまた書くのは面倒くさいですよね。
こんな時に便利なのが継承です。
EmojiMailクラスを作る際に、親クラスとしてMailクラスを指定すると、Mailクラスの持っている能力(プロパティやメソッド)をそのまま引き継ぐことができます。
同じ処理をもう一度書く必要はありません。
EmojiMailクラスに書くのは、親クラスが持っていない「絵文字を送る」という処理だけでOKです。
また、親クラスが持っている機能を上書きして書き換えることもできます。
例えば、メールを実際に送る「send」というメソッド(関数)があった場合に、Mailクラスの場合は「通常のメール」を送りますが、EmojiMailクラスの場合は「絵文字に対応したメールを送る」といった形です。
◆ポリモーフィズム(使う側は呼び出し方を統一できる)
このように定義しておくと、呼び出し側は、何も考えずに「send」というメソッドを呼ぶだけで、インスタンス化したのがMailクラスなら「通常のメール」インスタンス化したのがEmojiMailクラスなら「絵文字メール」を送ってくれます。
sendという統一した命令を行えば、それぞれのクラスに応じた動きをしてくれるという訳ですね。
これが、2つ目のメリット「ポリモーフィズム」という機能です。
これによって、
クラスの機能に追加や修正があった場合にも、呼び出し側のコードをいちいち修正する必要がありません。
呼び出し側は「send」と呼んでおくだけで、あとはいい感じに処理してくれます。
◆カプセル化(外部に触らせる必要の無いデータは隠すことができる)
変数を煩雑に管理していると、何かの間違いで変数の内容が書き換えられてしまったりしてバグの元になります。
しかし、クラスの中に定義された変数(プロパティ)は、クラスの外部に見せるか見せないか、というスコープを設定することができます。
外部に見せない設定を行えば、そのプロパティはクラスの中だけで書き換えることができ、外から書き換えたい場合もクラスのメソッド経由で書き換える形になるため、より安全になります。
これが、3つ目のメリット「カプセル化」という機能です。
良いコードを書くことがオブジェクト指向につながる
このように、オブジェクト指向には様々なメリットがあります。
変数や関数をばらばらに管理するのではなく、ある特定の役割を行う「オブジェクト」として定義することで便利に再利用できたり、継承、ポリモーフィズム、カプセル化といった手法で、よりスマートで安全なコードを書くことができるという訳ですね。
ただ、自分の書いたソースコードを「より見やすく」「よりシンプルに」書いていくと、自然とオブジェクト指向的な考え方になっていきますので
オブジェクト指向の概念を頭で理解しようとするよりも、見やすく効率的でバグの少ないコードを書くことを意識していくことが1番大事だと思います。
まとめ
・オブジェクト指向とは、一連の処理に使う「変数」や「関数」をひとまとめにして、再利用できるように名前をつけてテンプレ化しておこう!というプログラミング手法。
・クラスという金型を作り、実際に使う際はインスタンスを生成する。
・継承、ポリモーフィズム、カプセル化という便利な機能も使うことができる。
・見やすく、効率的なコードを書くことがオブジェクト指向につながる。