このページをはてなブックマークに追加このページを含むはてなブックマーク このページをlivedoor クリップに追加このページを含むlivedoor クリップ

目次

オブジェクト指向

 オブジェクト指向(object oriented)はシステムの提供する多くオブジェクトでアプリケーションなどを効率良く動かすという概念である。

 現在はJava、C++、PHPなどの多くのプログラミング言語で採用されている概念である。

 例を使って説明する。BASIC/C言語/Javaにおいて、「hello,world」を画面出力する部分を抜き出す。

↓BASICの場合

  1
  2
PRINT "hello,world"
END

↓C言語の場合

Everything is expanded.Everything is shortened.
  1
  2
  3
-
|
!
void main () {
 printf("Hello World\n");
}

↓JAVAの場合

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
-
-
|
!
!
public class Hello {
 public static void main(String argv[ ]) {
  System.out.println("Hello World");
 }
}

 プログラムだけを見るとBASICが短いコードであり、Javaが長いコードになる。しかし、大きいプログラムの場合、Javaの方が効率的である。というのも、BASICにはサブルーチンの非独立性があるからである。簡単に言えば、BASICはサブルーチンの効率が悪いのである。また、C言語は関数という考え方によりプログラムを分割して構築できる。JavaはC言語の作業効率をさらに進化させたオブジェクト指向が利用できる。

オブジェクト指向の分析・設計

他の分析・設計技法との違い

 オブジェクト指向の分析・設計は基本的にウォータフォールモデルと同様の手順を踏む。しかし、分析の方法や設計の方法は異なっている。実世界を抽象化しコンピュータ上で表現(モデル化)する方法である。抽象化・モデル化する点は、どの方法でも同じであるが、「実体」だけでなく、「振る舞い」「機能」までも抽象化・モデル化する。また、動的な観点についてもモデル化することが、他の分析・設計技法と異なる。

オブジェクト指向の基本性質

クラスとインスタンス

 共通した性質を持つオブジェクトの集まり(抽象化したもの)をクラス(class)といい、個々のオブジェクトをインスタンス(instance:事実)という。

例:学生クラスのインスタンスは、「田中」「20歳」「男」「学年」などである。

 プログラミング言語でオブジェクトを扱うにはクラス(設計図)を元にオブジェクトの実体を作る。この作られた実態がインスタンスである。同一クラスから作られたインスタンスは同じフィールドとメソッドを持っている。よって、オブジェクト指向プログラミングの際にはクラスの定義、インスタンスの作成が行われる。

属性とメソッド

 オブジェクト指向ではオブジェクトは性質(状態)と振る舞い(動作)の2つの要素で構成されている。前者の「状態」の要素はオブジェクトに共通の性質であり、属性(attribute)と呼ばれる。一方、後者の「振る舞い」の要素はオブジェクトが役割をなす動作であり、''メソッド(method)と呼ばれる。

[補講]Javaではこの属性をフィールドと呼ぶ。

例1:

  • 学生クラスの属性は、「氏名」「年齢」「性別」「2年」などである。
  • 学生クラスの属性は、「勉強する」「就職活動する」「サークル活動をする」などがある。

例2:「携帯電話」というオブジェクト(物)は「カラー表示ができる」「電池持ちがよい」などという性質(状態)、「ダイヤル先のベルを鳴らす」「相手にメールを送る」「アラームを鳴らす」などという振る舞い(動作)を持っている。即ち、携帯電話のフィールドが「カラー表示ができる」「電池持ちがよい」など、メソッドが「ダイヤル先のベルを鳴らす」「相手にメールを送る」「アラームを鳴らす」などとなる。

メッセージ

 オブジェクトはその手続きを実行させるための作業依頼を受けると動作する。また、必要なら他のオブジェクトに対してメッセージを出して動作させることもある。このようにオブジェクト間での作業依頼をメッセージ(message)と呼ぶ。

 オブジェクト指向では、オブジェクトの手続き(振る舞い)を動作させるメッセージのやり取りによって手続きが実行される。メッセージを受けて動作する手続きを記述したものがメソッドに該当し、メソッドは情報隠蔽により隠されている。

例:先生オブジェクトは、学生オブジェクトに「宿題を出す」メッセージを送る。プログラムで実行されるのは、クラスではなくオブジェクトである。

オブジェクト指向の基本概念

カプセル化

 属性とメソッドを一体化して、オブジェクトとすることをカプセル化(encapsulation)という。データと操作を一体化してデータを隠蔽することである。オブジェクト間の相互依存性を低くすることができる。つまり、オブジェクトの内部仕様の詳細と、外部から利用する場合に必要な最小限の外部仕様とを分離できる。

 このカプセル化により、オブジェクトを利用して開発したい者は、データ構造などを知る必要はなく、メソッドとその振る舞いだけを理解すればよいことになる。

「汎化-専化」関係と「集約-分解」関係

 E-R図のエンティティの関係にあった「汎化-専化」(is-a)関係と「集約-分解」(part-of)関係は、オブジェクト指向でも存在する。

「汎化-専化」関係

 汎化は子クラスの性質を抽象化することで、「バスを一般化したものが自動車」という関連である。一方、専化(特化)は親クラスの性質を継承して具体化することで、「自動車を専門化したものがバス」という関連である。

「集約-分解」関係

 分解は親クラスの性質を分割して子クラスにすることで、「エンジンは自動車の一部」という関連である。一方、集約は子クラスを集めて親クラスにすることで「自動車はエンジンを持つ」という関連である。

継承(インヘリタンス)

 汎化関係を持つクラスは、抽象化された上位概念のスーパークラス(super class)と下位概念のサブクラス(subclasss)から成る。また、スーパークラスの属性とメソッドは、サブクラスに引き継がれ、これを継承(インヘリタンス)という。

 継承によって、複数で分担開発を行っている際に間違えて重要なデータを消してしまうというトラブルを少なくさせることができる。なぜならば、重要なデータほどスーパークラスであるからである。

 例えば、JAVAやPHPで既存のクラスを継承して新規クラスを作成するときは次のような書式で書く。

class クラス名 extends スーパークラス名{ 

 公式のように次を覚えればよい。

A extends B

 AはBを継承でき、このときAからみてBがスーパークラス、BからみてAがサブクラスになる。

オブジェクト指向の応用概念

多重継承

 サブクラスが複数のスーパークラスから継承することを、多重継承(multiple inheritance)という。サブクラスは両方のスーパークラスの性質(属性とメソッド)を引き継ぐことになる。

多態性・多様性

 異なるクラスのオブジェクトに対して、同じ名前のメッセージを送る時に、それぞれ異なる動作を起こすことを多態性・多様性(polymorphism:ポリモルフィズム)という。

 メッセージを送る側は、異なる動作を起こさせるための仕組みを省略することができ、インタフェースが簡略化される。

委譲

 本来、クラス間に「汎化-専化」関係がないにも係わらず、プログラムの実装の都合上、他のプログラムの実装内容を利用したい場合がある。

 例えば、「スタック」というクラスの実装にあたり、すでに存在している「リスト」というクラスの操作を利用する。スタックへの「プッシュ」(push)があれば、リストの操作の「挿入」を利用して、リストの先頭に要素を挿入する。また、「ポップ」(pop)があれば、リストの先頭の要素を取り出した後、リストの操作の「削除」を利用して、その要素を削除することで実現できる。

 このような操作の共有は、継承によっても実現できるが、「スタック」クラスを「リスト」クラスのサブクラスとして、操作を継承させた場合、スタック中の任意の位置に要素を挿入したり、スタック中の任意の位置の要素を削除したりという、本来「スタック」には許されない操作が可能となってしまう。こうした不都合を避けるために、他のクラスの操作を選択的に利用する機構があり、これを委譲(delegatin:デレゲーション)という。

伝搬

 伝搬(propagation)とは、あるオブジェクトに対して操作を起動した場合に、そのオブジェクトに関連する他のオブジェクトに対しても、自動的に操作が起動されることである。

 例えば、集約関係にあるような場合、上位の集約オブジェクトに対して操作を起動すれば、その集約オブジェクトを構成する部分オブジェクトに対しても、その操作が起動される。

役割

 役割(role)とは、関連のあるオブジェクトの一方の終端のことである。よって、2つのオブジェクト間での関連には2つの役割がある。

 例えば、「人」オブジェクトと「会社」オブジェクトの間で「働く」という関連がある場合、「人」オブジェクトの方の終端には「従業員」、「会社」オブジェクトの方の終端には「雇用者」という役割が付される。

オブジェクト指向の分析・設計・プログラミング

 オブジェクト指向は「静的な構造」「動的な振る舞い」「機能」についてモデル化する。それぞれオブジェクトモデル(オブジェクト図)、動的モデル(状態遷移図)、機能モデル(DFD:データフローダイアグラム)によって実現化される。それぞれのモデルは、次のような手順でプログラミングされることになる。

 分析工程では実世界をそのままモデル化するまでであるが、開発工程ではプログラミングできるまで仕様を明確化する。実世界を抽象化したモデルは、コンピュータ上で実現化されるまで、具体化されることになる。

オブジェクト指向の分析・設計の手順

 オブジェクト指向の難しい点は、実世界をモデリングすることである。最終的な形としてモデリングするまでには、試行錯誤の過程を踏むことになる。漏れはないか、分析結果に矛盾はないか、すでに作られたモデルが妥当かどうかなどの色々な観点から確認することになる。

 分析工程内だけなく設計工程も合わせて、こうした試行錯誤をしながら開発を進めるのが、オブジェクト指向の分析・設計の特徴である。このような開発方式をラウンドトリップという。

  1. 名詞を抽出する→クラス候補→クラス
  2. 動詞を抽出する→メソッド候補→メソッド・状態遷移図へ反映する
  3. 属性を抽出する→クラスの属性・状態遷移図へ反映する
  4. クラス間のメッセージを抽出して、DFDを記述する
  5. クラス間の関係(is-aやpart-of)を定義する
  6. サブジェクトを定義する

オブジェクト指向の分析・設計の技法

手法Shlaer&Mellor(シュレイアー&メラー)技法Coad&Youdon(コード&ヨードン)技法OMT技法Booch(ブーチ)技法
開発者S.ShlaerP.Coad, E.YourdonJ.RumbaughなどG.Booch
概要E-Rモデルを使用して、データ中心の対象世界をモデル化するE-R図やShlae&Mellor技法とOOPおよび知識データベースの概念を組み合わせて発展した構造化分析からデータフローと状態遷移図を受け継ぎ、オブジェクトモデリングはE-R図などの影響を受けているAda用の方法論だった旧Booch技法を拡張した。HOOD,OOSDなどのAda用の方法論からの影響が強い。E-R図やJSD法からも影響を受ける。
発表年1988年1990年1991年1991年
対象規模小〜大規模小規模小〜中規模中〜大規模
クラスオブジェクトクラスクラスクラス
属性属性属性属性フィールド
メソッドサービス操作操作
メッセージイベントメッセージ事象メッセージ
インスタンスインスタンスオブジェクトオブジェクトオブジェクト
階層上位型/下位型Gen-Specスーパークラス/サブクラス上位クラス/下位クラス
全体-部分関連付けオブジェクトWhole-Part集約using関係
関連関連付けオブジェクトインスタンス・コネクション関連using関係、undefine関係

Shlaer&Mellor技法

Coad&Youdon技法

 Coad&Youdon技法は、次の手順で行われる。

  1. クラスとオブジェクトの確定
  2. 構造の定義
  3. サブジェクトの定義
  4. 属性の定義
  5. サービス(メソッド)の定義

 対象とする領域の中から何をオブジェクトやクラスとして探し出すか、次の転地浮いて、その指針を示している。

  • 対象領域のどこを探すか
  • 対象領域の何を探すか
  • 何を考慮して、チェックするか

OMT技法

Booch技法

まとめ

 オブジェクト指向プログラミングでは、カプセル化の概念を用いてメソッドを介してデータを扱う。これによって、オブジェクト内部のデータ構造に変更があっても、呼び出し側のプログラムを変更する必要がなく、保守性の向上が期待できる。

 クラス構造の場合、スーパークラスで定義した操作をサブクラスで再定義することもできる。これをオーバーライドという。操作の再定義によって、同じ名前でも違った実装を持つことがある。実装が異なっても、それを呼び出すプログラムの違いを意識しなくてよいことをポリモルフィズム(多相性)という。

 プログラムによって生成されるオブジェクトの実体は、ヒープ領域に確保される。使用されなくなったオブジェクトの管理をプログラムで行うのは困難なので、ガベージコレクションによって領域内の不必要なオブジェクトの整理を行い、領域の再利用を図る言語処理体系がある。

[補講]SW H13午後1問2に上記の赤部分を埋める(選択ではなく、書き込み)問題が出ている。

参考文献

  • 『ソフトウェア開発技術者 合格エッセンシャルハンドブック』
  • 『ソフトウェア開発技術者試験対策 コンピュータサイエンス補足資料+午後演習問題』
  • 『一週間でマスターする Javaプログラミング for Windows』
  • 『図解でわかるiアプリプログラミング』
  • 『超図解mini 基本情報技術者試験 平成19年度版』