オブジェクト指向とは何か?ソフトウェア開発全般を支援する技術を解説
オブジェクト指向の概要
「オブジェクト指向」とは、業務分析から要求定義、設計、プログラミングまでソフトウェア開発全体を総合的に支援する技術の1つです。
オブジェクト指向は、Simula67というプログラミング言語から始まりました。
Smalltalkというプログラミング言語を開発したアラン・ケイ氏によって1967年頃に生み出された言葉とされています。
従来の開発思想とオブジェクト指向との違い
従来の開発思想とオブジェクト指向との違いをパンを焼く手順で表現すると、以下のようになります[1]Eric Freeman(著)、嶋田 健志(監修)、木下 哲也(翻訳)『Head First はじめてのプログラミング … Continue reading。
従来の開発思想
- 電源から加熱コイルを作成する
- 加熱コイルを電源に接続する
- 電源を入れる
- パンを取り出す
- パンをコイルの上2cmのところで持つ
- 焼き終わるまでその状態のままにする
- パンを取り除く
- 電源を切る
オブジェクト指向
- トースターにパンを置く
- トースターのボタンを押す
- 焼きあがったらトーストを取り出す
従来の開発思想は、「手続き型」と呼ばれるものです。
手続き型でパンを焼く手順を説明する時は、パンが焼きあがるまでの動作を1つ1つ説明しています。
一方で、オブジェクト指向では「トースター」という言葉を使って、パンを焼く手順を説明しています。
このように、オブジェクト指向ではトースターというモノ(オブジェクト)を使って、手順を説明しています。
もちろん、「トースター」がどのようなものなのかを説明しなければ、本当にこの手順でパンが焼きあがるのかは判断できません。
「トースター」が何者なのかを補足するのが後述する「クラス」です。
オブジェクト指向の特徴
オブジェクト指向には次にあげる3つの大きな特徴があります。
クラス
クラスはフィールド(共通変数)とメソッド(共通処理)をまとめるための仕組みです。
フィールドは外部から直接アクセスできないようにすることで、プログラム変更時の影響を最小限にします。
先ほどのパンを焼く手順の例で言えば、「トースター」というオブジェクトを説明するのがクラスです。
クラスは通常以下のように3つの領域に分けて表記します(括弧内はコードの例)。
トースター(Toaster) |
温度(temperature) 経過時間(elapsed_time) ボタン(button) |
取り込み(load) 焼き上げ(toast_it) |
クラスの1行目にはオブジェクトの名前、2行目には状態を表すための共通変数を、3行目にはそのオブジェクトが行う共通処理を記述します。
ポリモーフィズム
ポリモーフィズムは日本語では「多態性」と訳されることが多いです。
フィールドやメソッドが複数のクラスに属することを許容します。
クラスによってメソッドの振る舞いは異なります。
例えば、プログラミングで作った犬の「Dogクラス」と猫の「Catクラス」があったとします。
この2つのクラスは同じ鳴き声を出すという処理である「cryメソッド」を実装しているとしましょう。
しかし、その振る舞いはDogクラスでは「bow-wow」、Catクラスでは「meow」となります。
継承
継承とは、あるクラスの持つ属性(フィールドやメソッド)を別のクラスに引き継ぐ仕組みです。
このとき、継承元をスーパークラス、継承先をサブクラスと呼びます。
サブクラスでは、スーパークラスのフィールドやメソッドをそのまま使えるほか、サブクラス独自のフィールドやメソッドを定義できます。
複数のクラスに定義された共通処理をスーパークラスにまとめることが可能です。
なぜオブジェクト指向が必要なのか
オブジェクト指向が注目を集める以前は、構造化プログラミングが多くの技術者たちから支持を得ていました。
構造化プログラミングとは「わかりやすい構造でプログラミングすることが重要である」という考え方です。
具体的には順次構造、条件分岐、反復の基本三構造を用いることが提唱されました。
この基本三構造はシンプルかつ強力で、これまでのプログラミング手法で問題とされてきたGOTO文[2]プログラム内で任意の場所に無条件で移動する命令文の乱用による処理の複雑化を回避することに成功しました。
構造化プログラミングによって、プログラミングの生産性や品質は飛躍的に進化を遂げたといえます。
しかし、構造化プログラミングでも解決できない問題が残りました。
それは、グローバル変数の影響と共通処理の再利用性の低さです。
グローバル変数とは、プログラムのどこからでもアクセスが可能な変数のことです。
プログラムのどこからでも変数が書き換えられるということは、プログラムに変更を加える際に影響範囲が完全に把握しにくいということを意味します。
なぜなら、どの処理がグローバル変数を書き換えるのか1つずつ確認していかなければならないためです。
構造化プログラミングでも解決できないもう1つの問題は共通処理の再利用性の低さでした。
構造化プログラミングの時代にも共通処理はありましたが、再利用性が低かったため、ソフトウェア全体の規模からすると微々たるものでした。
そのため、構造化プログラミングでは共通処理をより大規模なものにすることが必要でした。
オブジェクト指向では、このグローバル変数や再利用性の低さをクラスやポリモーフィズム、継承で解決することができます。
クラスはグローバル変数をなくし、インスタンス変数へとかたちを変えました。
インスタンス変数はどの処理からでもアクセスできる変数ではないため影響は局所的です。
また、ポリモーフィズムや継承ではスーパークラスでメインとなる処理を作っておけば、サブクラスで振る舞いを変えることができ、共通処理の再利用性はより強力になりました。
どういうときにオブジェクト指向を使うのか
オブジェクト指向の始まりはSimula67というプログラミング言語でした。
しかし、オブジェクト指向はプログラミング言語の枠を超えて、要求定義や設計などのソフトウェア開発全般を支援する技術となりました。
代表的なものにUML(Unified Modeling Language)があります。
UMLはオブジェクト指向を用いてソフトウェア開発を行うためのツールです。
Languageという名前がついていますが、実態はオブジェクト指向を共通認識するための「図」です。
ソフトウェア開発における設計書としても利用されるシーンが多いです。