前回のプログラムの問題点
さっそくですが、前回の最後に示したObjectClassの定義のコードをご覧ください。
#ifndef _OBJECTCLASS_H_INCLUDE_ #define _OBJECTCLASS_H_INCLUDE_ /* クラスの定義 */ typedef struct _object Instance; struct _object{ char* name; int status; int (*message)(Instance* self); }; /* オブジェクト生成メソッド */ Instance* Object_new(char* name, int status); /* オブジェクト破棄メソッド */ void Object_delete(Instance* obj); #endif
一見きれいで何の問題もないクラスの定義に見えますが、実はこのコードには、重大な問題があることに気づくでしょうか。
その問題とは、オブジェクトを利用する側のプログラムで以下のようなコードを書くことで確認できます。
obj1->status = 100; /* メッセージを送信しなくてもオブジェクトの状態を変更してしまえる! */
前回の復習になりますが、OOPにおけるオブジェクトとは次のようなものでした。
- すべての情報はオブジェクトによって表現される
- オブジェクトは「自身に関する独自の情報(属性)」と「機能(振る舞い)」から構成され、それらをオブジェクト自身で管理する
- オブジェクト間の相互作用はメッセージによって実現する
前述のとおり、前回お見せしたサンプルでは、メッセージを送信しなくても直接属性を変更できてしまえるため、上記の2および3を十分に満たしているとは言えません。また、一見処理とデータの組み合わせがきちんと表現できているように見えても、データへのアクセスが全然限定的になっていません。そのため、「安全にプログラムを取り扱う」というOOPの旨味も十分実現できているとは言えず、これでは十分なオブジェクト化が実現できているとは言えないのです。
では、十分なオブジェクト化を実現するためには、どのようにすれば良いのでしょうか。ここで登場するのが、「カプセル化(encapsulation)」という概念です。