仮想オフィスを活用したITエンジニア研修とは?
- 1.オブジェクト指向とは
- 2.オブジェクト指向に関連するワード
- 3.オブジェクト指向の3つの原則
- 4.オブジェクト指向を使うメリット
- 5.オブジェクト指向を使うデメリット
- 6.オブジェクト指向が難しいとされる原因
- 7.オブジェクト指向を使ったプログラミング言語
Javaをはじめとする多くのプログラミング言語は「オブジェクト指向言語」と呼ばれています。
そこで思うことは、「オブジェクト指向って何だろう?」ということでしょう。
本記事では、「オブジェクト指向」の特徴や原則について紹介していきます。
1.オブジェクト指向とは
オブジェクト指向とは、システム全体を「モノ」に見立てた「オブジェクト」の集合体として考えることで、より人間がわかりやすい構造を保つための仕組みです。
オブジェクト指向にもとづいてプログラミングを行うことを「オブジェクト指向プログラミング」と呼びます。
また、このオブジェクト指向の概念にもとづいて設計・開発されたプログラミング言語を「オブジェクト指向言語」と呼んでいます。
……このような説明は「オブジェクト指向」について検索するとよく出てくるでしょう。でも、これを読んだだけではいまひとつイメージがつきづらいのではないでしょうか。
ぜひ、最後まで読んでから再度この文章を読み返してみてください。
① オブジェクト指向が誕生したきっかけ
オブジェクト指向の考え方が生まれたのは1950年代で、MITのアラン・ケイ氏によって提唱されました。
(余談になりますが、同氏はその後1970年代に登場したオブジェクト指向言語のさきがけともいわれる「Smalltalk」に携わっています。)
元々は人工知能の分野で、数値計算の結果と現実世界の情報を紐づけるために利用したことがはじまりとされています。
そこから、現実世界の情報を「モノ=オブジェクト」として定義し、プログラミングの考え方に展開していきました。
②オブジェクト指向と手続き型言語
オブジェクト指向を採用した言語と対比されるのが「手続き型言語」です。
手続き型を採用しているプログラミング言語として有名なのは、FORTRANやCOBOLといった歴史のある言語です。
手続き型は、プログラムを実行単位で分割し、順次実行することに長けたプログラミングの手法。もっと簡単に言うと「プログラムの処理が順番に記述されている」のが手続き型言語の特徴です。
処理の順番がわかりやすい代わりに、機能の分割がしづらく、大規模なソフトウェア開発にはあまり向いていないといわれています。
元々、手続き型言語にはオブジェクト指向に関する機能は存在しませんでしたが、近年のバージョンでオブジェクト指向の考え方をサポートしている言語もでてきました。
また、Goのようにここ10年で使われ始めた新しい言語にも、手続き型言語の要素があります。
2.オブジェクト指向に関連するワード
ここでは、オブジェクト指向を理解するにあたって重要なキーワードを紹介していきます。
① オブジェクト
オブジェクト指向の基本概念として、システムとして考慮すべき対象を「モノ=オブジェクト」としてとらえています。
「学校」がひとつのシステムだとすると、「教室」「校庭」「下駄箱」など、大小さまざまなオブジェクトが考えられます。
端的にいうと、オブジェクトはオブジェクト指向を考えるうえでベースとなる「単位」であると考えましょう。
② クラス
オブジェクトはあくまでも概念的な存在であるのに対し、クラスはプログラム上でオブジェクトを表すための「設計図」です。
現実世界においては、同型の車がいくつも存在していますが、それぞれが違う個体として存在しています。
オブジェクト指向プログラミングの世界においては、このクラスの情報をもとにオブジェクトの実体が生成されるのです。
プログラムの世界においては、クラスから生成されたオブジェクトを「インスタンス」と呼びます。
③ プロパティ
プロパティは、そのオブジェクトがもつ「情報」を意味します。
たとえば、車であれば「色」や「ドア数」などといった情報がプロパティとして存在すると考えましょう。
プログラム上では、文字列や数字といった情報がプロパティとして格納されるほか、ほかのオブジェクトをプロパティとして保持することもあります。
④ メソッド
メソッドは、そのオブジェクトが持つ「ふるまい」を意味します。
たとえば、車であれば「カギを開ける」「エンジンをかける」「アクセルを踏む」などといった、操作に関する事項がメソッドとして存在すると考えましょう。
プログラム上では、プログラムの処理を記述することになります。
3. オブジェクト指向の3つの原則
オブジェクト指向でプログラミングをする場合に気をつけるべき3つの原則を紹介します。
これらの原則はプログラミング言語の仕様ではなく、あくまでも「プログラムをどう作っていくか」を考えるための概念のような存在です。
プログラムを作る際には、以下のことをしっかりと考えて「設計」する必要があると考えましょう。
① カプセル化
オブジェクト指向として大事な点として、「責務を分割する」という点があります。
「責務」というと難しいのですが、簡単に説明すると「外部から操作できる範囲を限定する」ということに主眼を置くとよいでしょう。
たとえば、現実世界をおいて家電製品の多くはスイッチで操作します。
最近では、声で操作するスマート家電も登場し、より簡単に操作できるものが増えてきました。
電子レンジであればボタンひとつで食品を温めてくれますが、内部的には複雑な処理を行っています。
ですが、利用者はその内部構造を理解しなくても使えるようになっていますよね。
このように、利用する側から見て使える(触れる)範囲を限定することで、予期しない挙動を防止するようなつくりとなっています。
この考え方が「カプセル化」です。
プログラミングにおけるカプセル化も考え方は同じで、クラスのプロパティやメソッドに適切なアクセス範囲を設定することで、予期しない挙動を防止する目的を果たします。
② ポリモーフィズム
オブジェクト指向の大事な考え方として、もうひとつ「ふるまい」という考え方があります。
そのふるまいを理解するなかで大事なのが「ポリモーフィズム(多様性)」です。
ポリモーフィズムは、簡単に説明すると「同じ意味なのに違う結果(ふるまい)が得られること」を指します。
少しプログラミングに考えを近づけるため、コマンド式のRPGを例に考えてみましょう。
RPGといえば、
・戦士
・魔法使い
・射撃手
・盗賊
・ヒーラー
など、さまざまなキャラクターがいます。
これらのキャラクターはそれぞれ違う武器を持っていることでしょう。
もちろんゲームによって異なりますが、戦士であれば剣を、魔法使いであれば杖や本を持っています。
また、同じ戦士でも片手剣、両手剣、短剣といった武器種を扱えるゲームもあるでしょう。
ですが、ゲーム上ではすべて「こうげき」のコマンドひとつで攻撃できます。
このように、「こうげき」というひとつのコマンドでもさまざまな結果(多様性)を得られるようにする構造を「ポリモーフィズム」と呼びます。
プログラムの内部的な話をすると、戦士や魔法使いといったキャラクターには「こうげき」というメソッドを共通で用意し、
戦士.こうげき()
魔法使い.こうげき()
といったように使います。
③ 継承と抽象化
もうひとつ、ポリモーフィズムやカプセル化と関連して大事なのが「継承」という考え方です。
先ほどのRPGのキャラクターでは、「こうげき」という共通のコマンドを用いて敵へ攻撃すると説明しました。
ここで、戦士の「こうげき」と魔法使いの「こうげき」は本当に同じなのか?という疑問が生まれます。
この疑問を解消するのが「継承」という考え方です。
RPGのキャラクターであれば、職業は異なりますが実際に動かすのは登場人物を表す「キャラクター」という概念です。
職業ごとにまったく異なる特性を持っていたとしても、「キャラクター」という大枠の存在に収まっています。
このように、オブジェクトを分類化して共通項を見つけ出すことを「抽象化」と呼びます。
たとえば、RPGのキャラクターであれば以下のように抽象化できるでしょう。
最も大きな枠として「キャラクター」が存在し、その中にプレイヤーが操作できる「プレイアブルキャラクター」と操作できない「NPC」が存在します。
プレイアブルキャラクターへの操作としては、移動や戦闘に関する細かい操作を定義できます。
各職業のキャラクターは、抽象化した「キャラクター」や、それをさらに継承した「プレイアブルキャラクター」を継承しているのです。
「こうげき」を「プレイアブルキャラクター」のメソッド(ふるまい)として定義することで、どの職業においても同じ「こうげき」として扱えます。
一方で、NPCは「キャラクター」として扱えますが、プレイアブルキャラクターのメソッドを持っていないため、プレイヤーが操作することはできません。
このように、継承をうまく活用することで、カプセル化とポリモーフィズムを実現できるのです。
4.オブジェクト指向を使うメリット
オブジェクト指向の概念や考え方を紹介してきましたが、オブジェクト指向でプログラミングするメリットは結局あるのでしょうか?
ここでは、実際の開発におけるオブジェクト指向のメリットを紹介します。
① プログラムの全体像を把握しやすい
オブジェクト指向の大きな特徴は、オブジェクトごとに「責務」を分割することにあります。
オブジェクト指向の考え方に沿って綺麗に分割されたプログラムは一覧化しやすく、管理しやすいというメリットが生まれます。
たとえば、「〇〇の管理をしたいのであればXXのコードを見ればいい」ということがすぐに判別できるほか、カプセル化によって責務と呼び出し方を容易に想像できるのです。
② 開発の効率が上がる
綺麗にカプセル化ができているコードは、相互干渉の少ない、いわゆる「疎結合」な状態で完成します。
そのため、自分が作るプログラムの範囲を把握しやすく、複数人で開発を進める場合でも分担しやすいというメリットをもちます。
③ バグを特定しやすい
大規模なソフトウェア開発をするうえで気をつけないといけないのが「影響範囲」です。
たとえば、AというプログラムをB・Cという2つのプログラムが利用していたとします。
その後、プログラムBに問題があり、プログラムAを直す必要が出てきました。
このとき、「プログラムCはプログラムAを使っている」ということがあらかじめわかっていたので、プログラムAの修正に伴い、プログラムCも再度テストすることにしました。
すると、プログラムCのテストがうまく動かずエラーとなってしまったのです。
このとき、オブジェクト指向にもとづきプログラムのカプセル化が機能していれば、エラー内容からどこでエラーが発生したのかが一目瞭然ですよね。
また発生したエラーを見れば、プログラムAとプログラムCのどちらに問題があるのかもわかりやすいことが多いです。
オブジェクト指向にもとづいて整理されていないプログラムは、相互に入り組んだいわゆる「スパゲッティコード」になりがちです。
スパゲティコードは可読性も下がるため、バグの温床になるだけでなくメンテナンス性も大幅に低下します。
バグを少しでも減らすためにも、正しいオブジェクト指向でクラス設計をすることが大事です。
5.オブジェクト指向を使うデメリット
ここまではオブジェクト指向に関する良いところを紹介してきましたが、もちろんデメリットも存在します。
オブジェクト指向でプログラミングをするにあたり、これらのデメリットをしっかりと理解して取り組むようにしましょう。
① 設計に時間がかかる
これまで紹介した通り、オブジェクト指向プログラミングのメリットの多くは「きちんと設計された状態」ではじめて発揮するものばかりです。
つまり「きちんと・きれいな」設計をしないと、オブジェクト指向のメリットを享受できないばかりか、新たな問題を生み出す可能性もあります。
時間をかけてしっかりと設計をしていくことが重要であることを忘れないようにしましょう。
② 理解するのが難しい
オブジェクト指向は、プログラムの世界を離れて現実世界とリンクするような設計をすることが多いため、理解するのに時間がかかります。
大人数での開発であれば特に、個人ごとにオブジェクト指向に対する理解度も大きく乖離している可能性もあります。
その結果、非常に複雑な構造をもつクラスが大量に作られる。なんていうこともあります。
実際のところ、オブジェクト指向言語を利用していながら、手続き型言語と同じような開発手法をとっているような現場もあります。
正しいオブジェクト指向を理解している開発者は多くない、という事実は忘れないでおくとよいでしょう。
6.オブジェクト指向が難しいとされる原因
「オブジェクト指向は難しい」という意見が散見されますが、その主な原因はオブジェクト指向が「概念的な考え方」でしかないという点です。
これまで解説してきた通り、オブジェクト指向とは「こういった考え方なのだ」という説明しかできず、明確な正解があるわけではありません。
7.オブジェクト指向を使ったプログラミング言語
さいごに、オブジェクト指向を採用しているプログラミング言語を紹介します。
① C++
C言語を拡張する形で作られたプログラミング言語で、ゲームや組み込みといった現場で使われています。
② Python
データ分析や数値計算を得意とするプログラミング言語で、主にAIの分野で活躍しています。
関連リンク:Pythonでできることとは?初心者向けにわかりやすく解説。学び方やおすすめ書籍も
③ Java
日本国内で最も人気があるプログラミング言語であり、多くのシステム開発の現場で利用されています。
Webからバッチまで幅広い開発が可能であることから、COBOLを用いた古いシステムからの移行先にJavaが選ばれています。
関連リンク:Javaとは? 歴史や特徴、学習方法やサービスなど初心者向けにわかりやすく解説
④ JavaScript
主にWebブラウザ上で動作するJavaScriptも、クラス構文を用いたオブジェクト指向プログラミングが可能です。
⑤ PHP
主にWeb業界で利用されるプログラミング言語で、ブログ作成に用いられるWordPressはPHPで開発されていることで知られています。
もともとPHPにはオブジェクト指向の概念が存在しませんでしたが、1998年にリリースされたPHP3からオブジェクト指向をサポートしました。
⑥ Ruby
日本人が開発したプログラミング言語で、シンプルかつ高い拡張性をもっているのが特徴です。
高速開発フレームワークである「Ruby on Rails」を利用することで、非常に生産性の高いWebアプリケーションの開発が可能です。
⑦ Scratch
Scratchは、ゲーム開発ができる「ビジュアルプログラミング言語」です。
コードを文字で書くのではなく、ブロックで表現した命令をドラッグしてつなげることでプログラミングしていきます。
直感的なプログラミングが可能であるため、多くの小学生がScratchでのゲーム開発にチャレンジしています。