プログラミング

いまさら聞けないオブジェクト指向とは?初心者にも分かりやすく解説します

プログラミングを勉強されている方であれば、1度はオブジェクト指向の恩恵を享受したことがあると思います。

しかし、これきちんと理解するには、かなり難しいと思います。

そこで、なぜ理解しづらいのかを踏まえながら、オブジェクト指向について初心者にも分かりやすく解説します。

今回は下記の書籍を参考にしました。

オブジェクト指向でなぜつくるのか 第3版 知っておきたいOOP、設計、アジャイル開発の基礎知識 [ 平澤 章 ]

オブジェクト指向はなぜ難しいのか

オブジェクト指向は便利で、プログラミングをしている人であれば誰でも使っている仕組みであるのに難しく奥が深い仕組みです。

なぜ難しいのか、僕自身もなぜ苦労したのか、いくつか思い当たる理由があるので紹介します。

オブジェクト指向の仕組みが複雑

オブジェクト指向には、たくさんの仕組みが存在します。

基本的な仕組みを挙げるだけでもクラス、インスタンス、インスタンス変数、メソッド、継承、ポリモーフィズム、スーパークラス、サブクラスなど。

多すぎて分からないですよね。

コンピュータ内での動作も多いためイメージしづらく、これらの言葉1つ1つがかなり理解しづらいと思います。

僕もなにがなんだが頭の中が混乱するということよくありました。

しかし、これだけ多くの仕組み構成されるオブジェクト指向を使いこなせると、コードを書くときにかなり楽になるとはずです。

比喩を用いた説明

比喩を用いた説明で混乱するということがあります。

オブジェクト指向の仕組みは、現実世界の例を用いて説明されることが多いです。

例えば、

クラスは、オブジェクトを作成するための設計図で自動車を例に考えてみると、自動車を作る元となる設計図、インスタンスは設計図を元にして生成する「青いトラック」、「赤い車」である。

こうした説明をすることでオブジェクト指向の複雑な仕組みを印象的に伝えることができます。

しかし、これがかえってわかりづらく比喩の方が印象的に残ってしまい、なんとなく理解したという状態につながります。

現実世界とオブジェクト指向は、似ていますが全く別物です。

僕も比喩的な説明が多く、曖昧な理解になっていたと思います。

本記事では、できるだけこのような説明はせずに解説してきます。

オブジェクト指向とは

オブジェクト指向は、1997年にノルウェーで考案されたSimula67(シュミラ67)というプログラミング言語が起源となっています。

この言語は、クラス、ポリフォーフィズム、継承というそれまでなかった優れた仕組みを備えています。

オブジェクト指向の主な言語は、「Java」,「Python」,「C++」,「Ruby」といった言語があります。

このオブジェクト指向を利用すると、これまでの大規模なソフトウェアの再利用部品群を作ることが可能になりました。

クラスライブラリやフレームワーク、再利用部品群を作る際に利用されたお決まりの設計アイデアとしてデザインパターンなどが作られました。

オブジェクト指向3大要素

オブジェクト指向の3大要素と呼ばれるクラス(カプセル化)、ポリモーフィズム、継承について解説します。

クラス(カプセル化)

クラスの特徴
  1. メソッドや変数を「まとめる」
  2. クラス内部でメソッドや変数を「隠す」
  3. 1つのクラスからインスタンスを「たくさん作る」

クラスには、3つの特徴が存在します。

次は、上記の3つの特徴について詳しく説明します。

まとめる

クラスにより、メソッドや変数をまとめることができます。

これにより、まとまりごとに分けることで整理整頓ができます。

比喩で説明すると、散らかった部屋を掃除するのに大きな箱を用意するのではなく、複数の箱を服、化粧品、文房具などに分けて整理する方が便利であると同じ意味です。

これがそんなに重要な仕組みなのか?

大規模な開発になれば、ソースコードは1万行、10万行になることは珍しくありません。

そうなった時に、まとまりごとに分けておくことはとても重要な仕組みです。

オブジェクト指向とオブジェクト指向より前を比較するとこのようなになります。

オブジェクト指向より前の場合

TextFileOpen()
TextFileClose()
TextFileRead()
JsonFileOpen()
JsonFileClose()
JsonFileRead()

オブジェクト指向の場合

■ Txetクラス
FileOpen()
FileClose()
FileRead()
■ Jsonクラス
FileOpen()
FileClose()
FileRead()

オブジェクト指向では、Textクラス、jsonクラスと整理されていることが分かります。

隠す

クラス内部でメソッドや変数を隠すことができます。

プログラミングをされている方であれば、「private」と記述されたことはありませんか?

これにより、アクセス範囲を制限することができ、決められた手段以外の不正なアクセスを防ぎ安全性が向上します。

また、アクセスできる範囲を限定しておくことで、不要な値が入ること防ぐことができます。

たくさん作る

クラスを定義することで、インスタンス変数をたくさん作ることができます。

インスタンスを利用する側は、インスタンスを指定してメソッドを呼び出すことができるため、どのインスタンスにメソッドを指定するかを決めることができます。

ポリモーフィズム

ポリモーフィズムは、簡単言うと「異なるクラス間の類似したメソッドを共通化しただけ」のものです。

たったそれだけのことですが、三大要素と呼ばれているのはなぜでしょうか?

ここでは詳しい説明は省きますが、類似したメソッドを共通化することで呼び出す側は、共通化されたメソッドを呼び出すだけで良くなります。

以下のイメージ図を用いて解説します。

人間クラスに「attack」(攻撃)という関数(メソッド)があるとします。

そして、人間クラスのサブクラスには剣士クラス、狙撃手クラス、魔法使いクラスがあり、それぞれ「attack」(攻撃)という関数(メソッド)の中身を独自で実装しています。

その結果、人間クラスの「attack」(攻撃)を実行すると、剣士クラスのオブジェクトは「斬撃攻撃」、狙撃手クラスのオブジェクトは「射撃」、魔法使いクラスのオブジェクトは「魔術攻撃」を実行します。

このように、呼び出し側は同じ「attack」(攻撃)という処理を実行しているが、命令を受け取ったオブジェクト側でそれぞれ異なる動作をするのが「ポリモーフィズム」です。

継承

継承とは、クラスの共通部分を別クラスにまとめて、コードの重複を排除するものです。

継承される共通クラスを「スーパークラス」、継承した新しく作ったクラスを「サブクラス」といいます。

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

オブジェクト指向のメリットを勘違いしないでください。

オブジェクト指向の三大要素は、手段であって目的ではありません。

保守性、汎用性、拡張性などを確立することが目的です。

この考え方は、めちゃくちゃ重要で僕もオブジェクト指向を勉強する時に意識したかったことです。

その考え方を踏まえてオブジェクト指向のメリットについて紹介します。

共同開発できる

オブジェクト指向は、機能ごとに分けて開発できるため、大人数で並列して作業することが可能となります。

他の開発者が書いたコードを「継承」して共通化したり、作業を細分化することができるため、より効率良く開発することができます。

アジャイル開発、スクラム開発などといった開発手法がありますが、これらもオブジェクト指向の対価を受けたものだといえます。

メンテナンスしやすい

開発することも重要ですが、運用、保守していくことも同じくらい重要なことです。

オブジェクト指向では、小さなまとまりで分けて管理することができるため、コードが楽に管理できます。

また、小さなまとまりに分けることで改修による影響も減り、メンテナンスしやすくあります。

汎用性が高い

「ポリフォーフィズム」、「継承」などの概念を用いることで既存の機能を引き継ぐことができます。

デザインパターンなどが1種の分かりやすい例です。

まとめ

本記事では、初心者でも分かりやすくオブジェクト指向について解説しました。

オブジェクト指向は、複雑で難しい仕組みですがそれだけに便利で汎用性の高い仕組みです。

この仕組みのおかげで享受している恩恵がたくさんあり、エンジニアにとっては必須の知識です。

しっかり理解できるようになりましょう。