オブジェクト指向というと、今では特段珍しくもない概念、言葉ですが、相変わらずこれをしっかり理解したい!というニーズはあるようで、そういう本はコンスタントに売れるようです。
私は、アセンブリ言語、C言語からプログラミングの世界に入っているので、オブジェクト指向以前の原始人なのですが、そういう人間がいかにオブジェクト指向に馴染んでいったか書くのも一興と思い、書いてみることにしました。
C言語には、構造体というのがあって、異なる型の変数群をまとめることができました。個々の変数は、メンバ変数と呼ばれます。
struct s_tag {
int i;
char c;
single s;
double d;
};
struct s_tag s;
s.i =0;
s.c = ‘a’;
s.s = 1.024;
s.d = 3.14;
このように、構造体変数sを宣言したら、メンバ変数にはピリオド(ドット演算子)でつないでアクセスできます。
私が最初に接したオブジェクト指向言語は、C++でした。C++はCに対して大ざっぱに上位互換性を持っていますので、構造体が使えます。しかし、クラスというオブジェクト指向っぽい言語仕様をサポートしています。上の構造体は、そっくりクラスに置き換えられます。
class c_tag {
int i;
char c;
single s;
double d;
};
c_tag c;
C言語の構造体と違うのは、クラスではその実体を宣言するのに、class宣言子が必要ないということです(C++ではstruct宣言子もいりません)。また、クラスのメンバ変数に触ることは(原則)できません。
それは、structではメンバはデフォルトでpublicであり、classはprivateであるからです。なので、structと同じようにしたければ、publicアクセス指定子を置いて、そこからメンバの宣言を始める必要があります。
class c_tag {
public:
int i;
char c;
single s;
double d;
};
c_tag c;
c.i =0;
c.c = ‘a’;
c.s = 1.024;
c.d = 3.14;
しかし、これはオブジェクト指向的に正しくありません。オブジェクト指向の世界では、その中がどうなっているのかということは、極力隠すのです(カプセル化)。ですから、メンバ変数に直接アクセスできないように、アクセサを定義します。アクセサというのは、メンバ変数にアクセスするためだけのメンバ関数です。
class c_tag {
public:
int get_i();
void set_i(int a_i);
private:
int i;
char c;
single s;
double d;
};
int c_tag::get_i()
{
return i;
};
void c_tag::set_i(int a_i)
{
i = a_i;
}
c_tag c;
c.set_i(20);
とまぁ、本格的にやっていけばこの記事はこの100倍以上の長さになっても終わりませんが、
- publicなメンバ変数
- privateなメンバ変数
- アクセサ
- コンストラクタ
- 特定目的のメンバ関数
- デストラクタ
- 演算子オーバーロード
- 継承
- 関数オーバライド
- ………
というように順を追ってやっていけば、オブジェクト指向なるものはさほど難しいものではないと思うのです。個人的には、オブジェクト=モノ、という説明をするのは却ってわかりにくいのでは?と感じています。
いざ書き始めたらさほど面白くもない記事になってしまいましたが、いざC++のクラスについて改めて調べましたら、その仕様の膨大さに眩暈がしそうになりました。このあたりは、新しい言語であるJavaやC#などの方が洗練されていますね。