20.1.2 オブジェクト指向
オブジェクトとは,英語で「もの」という意味です。この言葉からもわかるように,オブジェクト指向とは,現実にある「もの」や,「もの」同士が作用し合うことによって作り出される「現象」を,そのままコンピュータの世界に反映しようという考えです。
- 〈この項の構成〉
(1) データ中心の考え方(生産面での問題点の解決)
従来のCOBOLプログラミングでは,実現したいシステムの処理(機能)を分析し,機能ごとのモジュールを段階的に,細かく分割する手法がとられます。こうした分割手法では,あるモジュールはその上位のモジュールの機能を実現するために必要な機能の一つとして存在します。このため,あるモジュールをまったく別のモジュール機能として,部分的に再利用するのは困難です。また,プログラムを変更したり拡張したりする際には,機能を実現するために使用されるデータが,どこで,何の目的で参照・設定されているのかを把握しなければなりませんでした。
オブジェクト指向では,実現したいシステムで使用されるデータを中心に考えます。システムの中で何らかの役割を担うデータをオブジェクトとして抽出し,データとそのデータに対して与えられる機能を一まとまりにしてモジュールを構成します。つまり,データを基にモジュールを分割する手法です。
このようにモジュールを分割すれば,同じデータを使用するシステムには,モジュールを再利用できます。また,データを直接参照・設定する部分がそのモジュールに限られるため,プログラムの修正や拡張も容易になります。
(2) オブジェクトの構造
オブジェクトとは,処理対象のデータとそのデータを操作する手続き(属性とサービス)をカプセル化したものです。次に例を挙げて説明します。
(例) Aさんの銀行口座のオブジェクト
Aさんは,ある銀行に普通預金の口座を開設しています。ここでは,普通預金の口座を例にして,オブジェクトを説明します。
Aさんの普通預金口座での処理をオブジェクト指向で実現させるために,必要な情報を抽出します。まず,この口座がAさんのものであるという情報が必要です。これらは,次に示す情報で表されます。
-
名前
-
口座番号
次に,Aさんの口座の状態を知るための情報を示します。
-
残高
-
利率
これらが,Aさんの口座であるということと,その口座の状態を認識するのに必要な情報です。これらの情報に対し,銀行の普通預金口座として機能を果たすために必要な動作として,次の三つを挙げてみます。
-
預け入れ
-
引き出し
-
振り込み
Aさんの口座は,「名前」や「口座番号」で認識され,「残高」に対し「預け入れ」や「引き出し」の処理を行うことができます。オブジェクト指向では,これらの情報をデータ,処理をメソッド(英語で手段を表す言葉)と表現します。
このような,Aさんの普通預金口座のオブジェクトは,次のような概念図で表せます。以後,このマニュアルではオブジェクトの概念図をこのように表します。
(3) カプセル化(保守面での問題点の解決)
オブジェクトを表す概念図は,オブジェクトのデータおよびメソッドの実装が隠ぺいされている状態を示しています。オブジェクト内のデータは,原則としてそのオブジェクトのメソッドによってだけ操作されます。また,オブジェクト内で変化したデータの値が,そのオブジェクトの外部のデータ値に,暗黙的に影響を与えることもありません。
このように,データもメソッドの実装もオブジェクト内に閉じ込め,外部から隠ぺいすることを,カプセル化といいます。
このカプセル化は,従来のプログラミング言語によるシステム開発で課題となっていた,データ間またはデータとプログラムの依存度の高さによって発生する変更時の障害を解消します。
(4) クラス
クラスとは,オブジェクトを生成するときの型のことです。オブジェクト指向では,クラスを使用してオブジェクトのデータ属性やメソッドを定義し,オブジェクトをカプセル化します。
クラスとオブジェクトの関係を銀行口座を例にして説明します。
銀行口座に必要なデータ(名前,口座番号など)と,それらのデータを操作するメソッド(預け入れ,引き出しなど)は,銀行口座クラスとして定義します。こうして定義されたクラスは,オブジェクトを生成するための型であり,だれの口座でもありません。実際の口座は,銀行口座クラスを基にオブジェクトとして生成します。各人の口座のデータの定義は同じですが,名前,口座番号などのデータには,それぞれ異なる値が設定されます。
(a) インスタンスオブジェクト
クラスから生成されるオブジェクトの実体のことを,インスタンスオブジェクトといいます。
一つのクラス定義から,複数のインスタンスオブジェクトを生成できます。生成されたインスタンスオブジェクトは,定義されたデータを個別に持っています。そのため,同じクラスから生成されても,それぞれのインスタンスオブジェクトは,固有のデータ値を持っています。
(b) ファクトリオブジェクト
同じクラスから生成されたインスタンスオブジェクトは,それぞれ固有のデータ値を持っています。しかし,中には口座オブジェクトの「利率」のように,各オブジェクトに共通するデータ値もあります。このようなデータをすべてのオブジェクトが持っていてもかまいませんが,まとめて1か所に保持しておく方が,保守しやすいオブジェクトになります。
ファクトリオブジェクトは,このように全オブジェクトに共通するデータを,1か所で管理するためのオブジェクトです。
例えば,「利率」を変更する場合,各インスタンスオブジェクトがそれぞれ「利率」を持っていると,それらをすべて変更しなければなりません。しかし,「利率」がファクトリオブジェクトに保持されていれば,ファクトリオブジェクトの「利率」だけを変更すればよいのです。
ファクトリオブジェクトは,一つのクラスに対して一つだけ存在します。
(5) メソッドの呼び起こし(メッセージパッシング)
オブジェクト指向では,データと処理は,それぞれにカプセル化されます。カプセル化されたデータは,他オブジェクトからの影響を受けてはなりません。このカプセル化という概念を守りながら,処理プログラムを実行させるために,オブジェクト指向ではメッセージを使用します。
メッセージとは,クラスからオブジェクトを生成させたり,またはあるオブジェクトが自分では処理できない問題の解決を,その処理ができるほかのオブジェクトに依頼するときに使用されるものです。次に例を示します。
(例)AさんがBさんの口座に現金を振り込む場合
AさんがBさんの口座に1万円を振り込もうとしています。しかし,Aさんの口座オブジェクトのメソッドは,Bさんの口座オブジェクトのデータを操作できません。そこで,Bさんの口座オブジェクトに次のようなメッセージを送ります。
このようにして,メッセージを介してオブジェクトのメソッドを操作することをメソッドの呼び起こし(メッセージパッシング)といいます。
(6) 継承(信頼面での問題点の解決)
継承とは,あるクラスが持つ性質をほかのクラスが受け継ぐことです。例えば,銀行が従来のサービスに新たなサービスを加えて,新しいサービスを提供する制度を設けようとした場合,継承を利用します。次に例を示します。
- 注
-
継承の矢印は,あるクラスがどのクラスを継承しているのかを示します。例えば,クラスBがクラスAを継承しているとき,矢印の向きもクラスBがクラスAを指します。
従来のサービスを持つクラスを継承したクラスでは,新しく追加するサービスだけを定義します。継承によって,従来のサービスが受け継がれ,使用できるようになっているので,これらのサービスについては定義する必要はありません。また,受け継いだ性質の再定義もできます。
このように,継承によって既存のクラスを利用して新しいクラスを作成すると,原始プログラム中のコーディングの重複が避けられるので保守資産の増加を抑えられ,システム開発にかかる労力を短縮できます。また,既存のクラスを利用することで,最初から品質が保証されている,信頼性の高いクラスを作成できます。
なお,このマニュアルでは継承されるクラスを「スーパクラス」,継承するクラスを「サブクラス」といいます。
(7) インタフェース
インタフェースは,このあとに説明する適合やポリモルフィズムに深くかかわっている重要な概念です。インタフェースは,オブジェクトがどのようなサービスを提供するのかを表します。具体的には,オブジェクトが持つメソッドの名前とパラメタの並び(これらをまとめて,メソッド原型といいます)の集まりから成ります。インタフェースは,オブジェクトが持つすべてのメソッド原型を表現することも,一部を表現することもできます。
(8) ポリモルフィズム
ポリモルフィズムとは,同じメッセージを送っても,メッセージを受け取るオブジェクトの生成元のクラスが異なれば,そのオブジェクトごとに異なる処理が行われる仕組みです。この仕組みを使用すると,複数の処理を一つのメッセージで実現できます。
次に例を示します。
(例)普通預金口座および当座預金口座からの引き出し
普通預金口座および当座預金口座は,それぞれ別のクラスから生成されたオブジェクトです。クラスが異なるので,それぞれのオブジェクトのメソッドに同じ名前を付けることができます。
これらのオブジェクトは,「引き出してください。」というメッセージを受け取ることができます。普通預金口座クラスのオブジェクトのメソッドは普通預金から現金を引き出します。当座預金口座クラスのオブジェクトのメソッドは,当座預金からの引き出しを要求する小切手をチェックして,現金を引き出します。つまり,同じメッセージであってもそれを受け取るオブジェクトのクラスが異なっていれば,異なる動作をするわけです。
ポリモルフィズムの仕組みは,メッセージのやり取りの単純化に役立ちます。また,新規に受け手のクラスを定義しても,メッセージの送り手側を修正する必要がないため,再利用性や保守性を向上させることができます。
- 注
-
COBOL2002では,メソッドが適合していなければメソッドに同じ名前を付けること(オーバライド)は,できません。
メソッドが適合しているかどうかは,マニュアル「COBOL2002 言語 標準仕様編」 「5.2.7(1) オブジェクト指向での「適合」」の規則に従ってチェックされます。