オブジェクト指向とは?エンジニアなら押さえておきたい考え方について!

オブジェクト指向とは?エンジニアなら押さえておきたい考え方について!

プログラミング言語の学習をしていると、オブジェクト指向という言葉に出会います。様々なプログラミング言語で取り入れられており、避けては通れない概念のひとつです。

必ず押さえたい概念にも関わらず、「オブジェクト指向は難しくて分からない」という方が多いのが事実です。今回は悩んでしまう方も多い、オブジェクト指向の考え方についてご説明します。

オブジェクト指向とはどのような考え方か

オブジェクト指向の名前は聞いたことがあるものの、具体的な考え方が分からない方は多いものです。最初にオブジェクト指向とはどのような考え方であるのか理解を深めましょう。

オブジェクト指向に明確な定義はない

実はオブジェクト指向に明確な定義はありません。冒頭でも少し触れた通り、オブジェクト指向はひとつの概念です。つまり、明確なルールがあるわけではなく、大まかにしか定義されていません。状況によって解釈が変わる曖昧なものなのです。

そのため、エンジニアの皆さんは「明確にオブジェクト指向の考え方を押さえたい」とは考えないようにしましょう。エンジニアである以上は細かな部分が気になるはずですが、オブジェクト指向において深追いは禁物です。人によって考え方や説明の仕方、用いる言葉が微妙に異なるので、永遠に完璧な理解はできなくなってしまいます。

とはいえ、何も説明を受けなければ永遠にオブジェクト指向の理解が進みません。以下ではざっくりとオブジェクト指向の考え方についてご説明します。

エンジニアにとってのオブジェクト指向とは

エンジニアにとってのオブジェクト指向は、「オブジェクトを利用していかに効率よくプログラムを開発するか」という部分に尽きます。色々な考え方がありますが、最終的に求められるのは効率よくプログラムを完成させることです。

一般的にプログラムを完成させるためには大きく分けて「設計」「実装」の2つの段階があります。それぞれの段階を担当する「システムエンジニア」「プログラマ」それぞれの目線でオブジェクト指向を理解していきましょう。

プログラマ目線のオブジェクト指向

プログラマ目線でのオブジェクト指向は、「クラス・オブジェクトに必要な変数と関数をまとめる」です。情報をバラバラに定義するのではなく、オブジェクト指向の概念を利用してまとめて定義するのです。

今までプログラマを経験しているのであれば、変数の定義や関数の利用で困った経験があるでしょう。変数がどこで定義されているのかわからなかったり、思わぬところで呼び出されていて困ったりするケースがあります。また、関数の定義方法が悪く、呼び出そうと思っても呼び出せない経験もあるはずです。

オブジェクト指向であれば、このようなバラバラな定義は「クラス」と呼ばれる概念で防げます。結果、バラバラに定義することによる問題を発生しにくくできるのです。

また、オブジェクト指向ではクラスによって変数や関数を定義しておきます。クラスは再利用が可能であり、同じ機能を持つものを複数回作成可能です。そのため、オブジェクト指向を利用すれば、繰り返しの記述を可能な限り減らしたプログラミングが可能です。

システムエンジニア目線のオブジェクト指向

システムエンジニア目線でのオブジェクト指向は、「いかに効率よく設計するか」です。オブジェクト指向にはクラスと呼ばれる概念があります。クラスを用いることで、変数や関数をあらかじめ定めておき、繰り返し利用することが可能です。

システムを設計するシステムエンジニアは「繰り返し利用できる」に注目が必要です。オブジェクト指向ではクラスによって繰り返しのプログラミングを防げますので、繰り返し利用ができるような設計をしなければなりません。

なお、繰り返し利用できるように万能な設計をしておくことを「汎化(はんか)」と呼びます。逆に繰り返し利用できない特定の設計を「特化」と呼びます。特化のシステム設計は簡単ですが、汎化のシステム設計は難しく、オブジェクト指向を活かせるかどうかの鍵を握ります。

オブジェクト指向の理解に必須のキーワード


上記までの説明で、「クラス」「オブジェクト」とあまりなじみのない言葉が出てきました。ここからは言葉の意味を改めて解説します。

クラス

クラスは後ほど説明するオブジェクトを生み出すための設計書です。変数や関数を設計書として定義しておいて、オブジェクトを生み出す際に参照します。テンプレートや雛形と表現すると分かりやすいかもしれません。

なお、オブジェクト指向を利用する場合、変数は「プロパティ」、関数は「メソッド」と呼ばれます。専門用語がありますが、ここでは変数や関数でイメージしておきましょう。

ここではクラスの理解を促進するために、RPGに出てくる「敵キャラ」を例に挙げてみます。「敵キャラ」は同じものが複数体で出現する可能性が考えられます。もしオブジェクト指向を利用しない場合、「敵キャラ1」「敵キャラ2」「敵キャラ3」のように全てを同じようにプログラミングする必要があります。

しかし、オブジェクト指向で「敵キャラ」というクラス(設計書)を定義しておけば、これを利用して同じ能力を持つ「敵キャラ1」「敵キャラ2」「敵キャラ3」を簡単に生み出せます。

なお、オブジェクト指向にはクラスを活用しやすいように様々な機能があります。それについては後ほどご説明しますので、まずはクラスとは設計書的な役割であることを理解しましょう。

オブジェクト

オブジェクトは設計書であるクラスから生み出されたものを指します。オブジェクト指向ではクラスを操作するのではなく、実際に生み出されたオブジェクトを操作します。クラスからオブジェクトを生み出すことをインスタンス化と呼び、オブジェクトではなくインスタンスと呼ぶ場合もあります。

先ほども説明したクラスはあくまでも設計書でしかありません。そのため、設計書があっても、実際には何もできないのです。例えば、家の設計書があっても人は住めませんので、クラスとオブジェクトには大きな違いがあります。

クラスからオブジェクトを生み出すことで、様々な情報の登録や操作を行えます。オブジェクトになることで初めて変数や関数が利用できるのです。例えば、上で説明したクラス「敵キャラ」に「名前」と変数があれば、ここに「敵キャラ1」などと具体的な値を格納できます。

また、同じクラスから複数のオブジェクトを生み出せます。先程の例のとおり、「敵キャラ」というクラスから「敵キャラ1」「敵キャラ2」「敵キャラ3」という複数のオブジェクトを生み出せるのです。そして、これらそれぞれに「名前」を格納することができます。

オブジェクト指向の理解を深める3大要素


オブジェクト指向を理解するにあたり、必須の要素が3つあります。それぞれどのような要素であるのかを解説します。

継承

継承は特定のオブジェクトが持つ機能を引き継ぐ(継承する)考え方です。プログラムを再利用して、開発効率を高めるために利用されます。継承を利用すると、複数のクラスで同じ内容を記述する必要がなくなります。

例えば、RPGに出てくる人間キャラとして「勇者」「魔法使い」「牧師」を考えてみましょう。これらのキャラクターには全員「性別」「役割」「攻撃力」と独自の「必殺技」が設定できるとします。

オブジェクト指向の考え方に基づくと、「勇者」「魔法使い」「牧師」それぞれのクラスを作ることは理解できるはずです。クラスからオブジェクトを生み出すことも理解はできるでしょう。今までの考え方では「勇者」「魔法使い」「牧師」にそれぞれ「性別」「役割」「攻撃力」「必殺技」の定義をしなければなりません。

しかし、継承を利用すれば、それぞれに「性別」「役割」「攻撃力」の定義が不要です。まず、これらは共通の要素ですので「人間」というクラスを作り、ここに「性別」「役割」「攻撃力」の定義をしておきます。

そして、継承を利用して「勇者」「魔法使い」「牧師」を定義します。継承元に「人間」を指定すれば、「勇者」「魔法使い」「牧師」に「性別」「役割」「攻撃力」の定義をしなくとも、「人間」の定義内容を引き継げるのです。つまり、同じ定義は記述する必要がなく「勇者」「魔法使い」「牧師」が持つ「必殺技」の部分のみを個別に記述すれば事足ります。

カプセル化

カプセル化は、オブジェクトが持つプロパティ情報を、外部から操作できなくするものです。簡単に説明すると、他のオブジェクトから勝手に操作されないように、隠す(カプセルに入れてしまう)仕組みです。

オブジェクト指向には色々な機能があり、これらを利用することで効率の良いプログラミングが可能となっています。その反面で、複雑なプログラミングとなりやすいことから、適切にプログラミングをしなければ誤操作によるバグが生まれやすくなってしまいます。

しかし、カプセル化を利用すれば、誤操作の問題を防ぐことができます。カプセルに入っているため勝手に操作できなくなり、オブジェクトに開発者が想定していない操作が加えられるのを防げるようになるのです。

とはいえ、カプセル化を利用すると全く操作ができなくなるわけではありません。開発者が「カプセルの中を操作する方法」を定義しておけば操作が可能です。例えば、「値を書き換える機能」を用意しておき、呼び出すことで、値を書き換えられます。

カプセル化を利用すると、誤操作によるバグを防げます。また、それぞれのクラスやオブジェクトを修正・変更・管理しやすくなります

ポリモーフィズム

ポリモーフィズムは「多様性」と日本語訳されます。オブジェクト内の同じ関数を呼び出しても、生み出されたオブジェクトによって実行結果が異なるものを指します。

基本的に同じクラスから生み出したオブジェクトは同じ変数と同じ関数を持ちます。同じ関数を持ちますので、動作結果も同じなのです。しかし、これでは不便な場合があります。その場合にポリモーフィズムが役立ちます。

例えば、先程の「勇者」「魔法使い」「牧師」が「挨拶」という関数を持っていたとします。また、「勇者」は「おっす」、「魔法使い」は「ハロー」、牧師は「こんにちは」と発言させたいとの要望がありました。そのために、今までの考え方ではクラスの内容を少し変えて、それぞれ別のクラスを作るしかありませんでした。

しかし、ポリモーフィズムを利用すると「挨拶」という関数の実行結果をそれぞれ変更可能です。同じ関数を呼び出しても、発言内容を変更できるのです。詳細な実装は割愛しますが、「同じ関数を似た別の関数のように利用できる」機能がポリモーフィズムなのです。

オブジェクト指向を利用するメリット


オブジェクト指向を利用すると感じられるメリットについても理解しておきましょう。

効率の良い開発がしやすくなる

オブジェクト指向を導入すれば、効率の良い開発を行えます。オブジェクト指向の概念なしでもプログラムは作成できますが、対応している言語ではオブジェクト思考を利用するべきです。

オブジェクト指向には「クラス」「継承」「カプセル化」「ポリモーフィズム」といった考え方があります。これらを利用すると「繰り返し」の実装が不要となり、プログラミングに必要な工数を減らせます。つまり、効率の良い開発がしやすくなるのです。

しかし、オブジェクト指向は複雑な概念が含まれています。そのため、エンジニアが慣れるまでは逆に実装ミスや理解ミスによるバグを含みやすくなってしまいます

修正・変更が容易になる

クラスを利用してオブジェクトを生み出す仕組みですので、同じクラスから生み出されたクラスへの修正・変更が容易です。クラスを修正すれば、全てのオブジェクトに同じ修正を加えられるのです。

例えば、クラス「ロボット」が「走る」「話す」との機能を持っていたとしましょう。このクラスから生み出されたオブジェクト「ロボットA」「ロボットB」に「返事をする」との機能を追加する場合を考えます。

この場合の機能追加は簡単で、クラス「ロボット」に「返事をする」との記載を追加するだけです。オブジェクト「ロボットA」「ロボットB」はクラス「ロボット」から生み出されていますので、クラスの修正をすれば自動的に生み出されているオブジェクトへ反映が可能です。

もしオブジェクト指向を利用していなければ「ロボットA」「ロボットB」のプログラミング部分にそれぞれ「返事をする」と追加しなければなりません。オブジェクト指向ならば1ヶ所の修正で済むものを、複数修正しなければならないのです。上記のように2ヶ所だけなら恩恵をあまり感じませんが、100ヶ所や200ヶ所になるとその差は歴然です。

まとめ

オブジェクト指向の基本的な考え方についても説明しました。オブジェクト指向は現在のプログラミングにおいて主流の考え方ですので、エンジニアならば必ず押さえておきましょう。

一回で理解できれば良いですが、オブジェクト指向は概念であり理解が難しい部分があります。そのため、可能な限りプログラミングの現場で、オブジェクト指向に実際に触れながら知識を深めていくのが理想的です。

SHAREこの記事をシェアする

admin