【問題8】オブジェクト指向の基本的な考え方:“組み込み力”向上! ETEC対策ドリル Step2(8)
今回は、大規模・複雑化が進む組み込みソフトウェア開発でも活用されているオブジェクト指向設計・プログラミングについて解説する。
前回の課題演習―【問題8】は、「オブジェクト指向」に関する問題でした。
近年、大規模化、複雑化が進む組み込みソフトウェアの開発では、オブジェクト指向設計・プログラミングを取り入れるケースが増えています。
今回は、問題の解答に続いて、“オブジェクト指向の基本的な考え方”について解説します。この機会にしっかりと理解しておきましょう。それでは、解答を発表します!
課題演習―【問題8】の解答
解答は、「ウ.既存のクラスの属性や振る舞いの機能を利用して新しいクラスを定義する」です。アは「多相性」、イは「カプセル化」、エは「汎化」の説明です。
構造化手法とオブジェクト指向
ソフトウェアに求められる機能を中心に考え、システムをサブシステム、さらにモジュールに分割して機能を詳細化し、モジュールをプログラミングして結合することでソフトウェア全体の構造を作り上げていく手法を「構造化手法」といいます。
例えば、ファイル処理を行うサブシステムでは、ファイルに対する「オープン」「読み取り」「書き込み」「クローズ」といった機能に着目してモジュール分割を行います。処理の対象となるファイルの情報は、関数の引数として各モジュールに渡します。ソフトウェア開発で古くから用いられている手法です。
構造化手法では、ソフトウェアの規模が大きくなるほど、モジュールの階層が深くなり、モジュール数が増え、管理が煩雑になりがちです。そうすると、モジュールの仕様変更の影響が広範におよび、修正漏れやミスが起こりやすくなります。
近年、大規模なソフトウェア開発に適しているとして、オブジェクト指向の開発手法を採用するケースが増えています。オブジェクト指向では、“システムが複数のオブジェクトから構成される”ものとしてとらえます。
例えば、ファイル処理の場合、処理の対象であるファイルオブジェクトが存在するものとします。ファイルオブジェクトは、ファイルの名前やサイズ、種類などの情報を「属性(フィールド)」として持ち、「オープン」「読み取り」「書き込み」「クローズ」などの「振る舞い(メソッド)」が定義されています。ファイルオブジェクトは、ほかのオブジェクトからの「メッセージ(メソッドの呼び出し)」をきっかけに、属性の値に応じて処理を行います。
では、なぜオブジェクト指向の開発手法は大規模なソフトウェア開発に適しているのでしょうか? その理由は、オブジェクト指向の概念であるカプセル化、継承、多相性にあります。
カプセル化
オブジェクトは、フィールドとメソッドを持ちます。例えば、ファイルからデータを読み取る場合、ファイルオブジェクトに対してメソッドを呼び出すことで、フィールドへのファイル名の設定、ファイルのオープンや読み取りなどを実行します。ファイルオブジェクトを利用するほかのオブジェクトに公開されているのはメソッドの呼び出し方法だけです。ファイル名のフィールドがどのような構造をしているのか、ファイルのオープンや読み取りがどのような手順で行われるかなどの詳細はほかのオブジェクトには分かりません。
オブジェクトの操作方法だけを公開し、データ構造や処理の詳細をオブジェクトに隠蔽(いんぺい)することをカプセル化といいます。カプセル化により、詳細を意識せずにオブジェクトを利用できるだけでなく、仕様が変更になってもオブジェクトの利用者側には影響がないため、開発の効率や保守性が向上します。
継承
まず、オブジェクトとクラスの違いについて理解しましょう。
ここに、「FileA」という名前のファイルがあります。容量は100バイトです。読み取りや書き込みはビット単位で行います。同様のファイルとして、50バイトの「FileB」や200バイトの「FileC」があります。これらのファイルはいずれもオブジェクトです。
「FileA」「FileB」「FileC」には、共通する特徴があります。まず、名前や容量などの属性を持ちます。振る舞いとして、ビット単位での読み取りや書き込みが行われます。このように複数のオブジェクトに共通する属性や振る舞いを抽出して定義するのがクラスです。
ファイルクラスは、いわば「FileA」などの名前を持つ具体的なファイルオブジェクトを生成するための枠組みになります。プログラム上では、ファイルクラスの名前フィールドや容量フィールドに具体的な値を設定することで、ファイルオブジェクトを生成し、ファイルオブジェクトを操作して処理を進めます。クラスからオブジェクトを生成することを、インスタンス生成と呼びます。
さらに、「TextA」というテキストファイルがあるとしましょう。属性として名前と容量を持つのは「FileA」ファイルと同じですが、読み書きは文字単位(バイト単位)で行います。この場合も同様の「TextB」や「TextC」に共通する特徴からテキストファイルクラスを定義できます。唯一、ファイルクラスとの違いは“読み書きの単位が異なる”ことです。このような場合は、ファイルクラスを基に、ビット単位で行う読み書きをバイト単位で行うように変更することで、テキストファイルクラスを定義できます。これが継承です。継承元のファイルクラスをスーパークラス(または基底クラス)、継承して作成したテキストファイルクラスをサブクラス(または派生クラス)といいます。
継承を利用すれば、既存のクラスから新しいクラスを定義できるため、開発の効率およびクラスの再利用性が向上します。スーパークラスでメソッドの仕様に変更があっても、サブクラスではその変更を意識する必要がないため、保守性も高くなります。
多相性
テキストファイルクラスは、ファイルクラスから基本的なフィールドとメソッドを受け継ぎます。そのため、テキストファイルクラスから生成されたテキストファイルオブジェクトは、見た目上はファイルオブジェクトとして扱うことができます。ただし、読み取りメソッドを呼び出すと、ビット単位ではなくバイト単位で読み取りを行います。見た目上はファイルオブジェクトでも、実際にはテキストファイルオブジェクトであり、そのように振る舞います。
ファイルクラスのサブクラスを幾つ定義しても、そのサブクラスのオブジェクトはファイルクラスのオブジェクトとして扱えます。しかし、その振る舞いは実際のオブジェクトの種類に応じたものになります。つまり、利用者側から見ると、ファイルの種類に関係なく、ファイルを読み取りたい場合には読み取りメソッドを使えばよいということです。この機能を多相性(ポリモーフィズム)といいます。
「is-a」関係と「has-a」関係
クラス同士がスーパークラスとサブクラスの継承関係にあることを「is-a」関係といいます。これは、サブクラスをスーパークラスの1種と見なすことができるからです。前述の例でいうと、テキストファイルはファイルの1種です。
また、スーパークラスはサブクラスを汎化、すなわちより抽象化したものと見なされます。逆に、サブクラスはスーパークラスを特化、すなわちより具象化したものになります。
一方、クラス同士が自動車と車輪のように、全体と部品の関係にあることを「has-a」関係といいます。has-a関係にはコンポジションと集約があります。コンポジションの場合、全体のクラスと部品のクラスの結び付きが強く、全体クラスのオブジェクトが削除されるときには、部品クラスのオブジェクトも削除されるようにしなければなりません。一方、集約は2つのクラスの結び付きが弱く、全体クラスのオブジェクトが削除された後も、部品クラスのオブジェクトは独立して存在できます。
課題演習―【問題9】
いかがでしたでしょうか? オブジェクト指向の概念について理解できましたか。次回は「単体テスト」や「結合テスト」について説明します。お楽しみに! (次回に続く)
Copyright © ITmedia, Inc. All Rights Reserved.