オブジェクト指向の基本−オブジェクト
オブジェクトとメッセージ
まず、オブジェクト指向の基本は何と言っても「オブジェクト(object)」です。オブジェクトは、オブジェクト指向における中心的な概念です。では、オブジェクトとは一体どのようなものでしょうか。その特徴を簡単にまとめると次のようになります。
- すべての情報はオブジェクトによって表現される
- オブジェクトは「自身に関する独自の情報(属性)」と「機能(振る舞い)」から構成され、それらをオブジェクト自身で管理する
- オブジェクト間の相互作用はメッセージによって実現する
そんなに難しくないですね。メッセージという新しい概念が出てきましたが、メッセージとは、オブジェクト同士のコミュニケーションの手段を抽象化した概念です。また、メッセージを受け取ってオブジェクトが行う処理の実体のことを「メソッド(method)」と呼びます。オブジェクトとメッセージにとって構成されるシステムのイメージを図2に示します。
このような考え方に基づいてプログラミングするメリットとは何でしょうか。オブジェクト指向の説明は現実世界の比喩から始まることが多いようですが、OOPで考えた場合には非常にシンプルになります。「プログラムとは処理とデータの組み合わせなのだから、それらの関連を明示的に示し、かつそれらへのアクセスを限定的にすることで、より安全にプログラムを取り扱おう」ということです。C言語でプログラミングする際には、普通に考慮することですね。例えば、ファイルスコープを利用して、処理とデータを1つの固まりとする方法などはよく行われているかもしれません。これを、オブジェクトとメッセージによって実現していくプログラミング手法がOOPなのです。
それではさっそく、オブジェクトとメッセージの概念をC言語を使って表現してみましょう(リスト1)。
#include <stdio.h>
/* Objectオブジェクトの定義・生成 */
int Object_method(void);
struct _object{
char *name;
int status;
int (*message)(void);
}obj = {"obj", 10, Object_method};
/* メソッドの実装 */
int Object_method(void)
{
printf("%s.status = %d\n", obj.name, obj.status);
return 1;
}
/* エントリポイント */
int main(int argc, char *argv[])
{
/* オブジェクトにメッセージを送信 */
obj.message();
return 1;
}
まず、objという名前のオブジェクトを、_object構造体を利用して定義・生成しています。次に、objオブジェクトが受け取ることができるメッセージmessageを、_object構造体のメンバの関数ポインタとして定義しています。また、メッセージを受け取って実際に行う処理をObject_method関数として定義し、オブジェクトの生成時にmessageにこのObject_method関数を指定することで、メッセージとメソッドの対応付けを行っています。最後に、main関数から、生成したオブジェクトにメッセージを送信しています。
このコードでのポイントは、以下の3点です。
- オブジェクトを構造体として表現している
- メッセージを関数ポインタとして定義している
- オブジェクトの生成時に具体的なオブジェクトの情報(データの値やメッセージに対応するメソッド)がセットされている
つまり、OOPにおけるオブジェクトとは、データと処理が格納されたメモリ領域に名前を付けたものなのです。リスト1では、データ(*name、status)と処理(Object_methodへの参照)を持つオブジェクト(obj)を構造体(_object)として表現することで、1.を実現しています。また2.のように、関数ポインタ(*message)を用いることでメッセージとメソッドの関係を表現しています。
リスト1の実行結果は、次のようになります。
>gcc oop1.c >./a.out obj.status = 10
簡単なコードではありますが、OOPの基本的な概念を実装するとどのようなものになるのかが確認できたかと思います。

