Deep Side of Java〜Java 言語再入門 第1回

「オブジェクト指向」とは

「オブジェクト指向」とは

「オブジェクト指向」とは、簡単に言えばデータと手続きを合体させることである。このようなデータと手続きが合体したものを「オブジェクト」と呼ぶ。つまり、データは自分にどのような操作が可能なのかを知っているのである。

このような「オブジェクト」はC言語でも作成可能である。たとえば、

struct LikeObject_tag {
        int x;
        int y;
        int (*add)( struct LikeObject_tag *p );
};

typedef struct LikeObject_tag LikeObject;

int LikeObject_add( LikeObject *p ) 
{
        return p->x + p->y;
}

void LikeObject_init( LikeObject *p, int x, int y )
{
        p->x = x; p->y = y;
        p->add = LikeObject_add;
}
....................

        LikeObject *lo = (LikeObject *)malloc( sizeof(LikeObject) );
        LikeObject_init( lo, 10, 20 );
        added = lo->add(lo);

このとき、構造体である LikeObject はそれ自身に関数ポインタを持ち、同じ型のデータに対して操作を行う。なので、データと手続きが合体した「オブジェクト」のようなものである。それに対して、本来のオブジェクト指向言語のオブジェクトでは、次のようにする。

class LikeObject {
        int x;
        int y;

        LikeObject( int x, int y ) {
                this.x = x;  this.y = y;
        }

        int add() {
                return this.x + this.y;
        }
}

....................

        LikeObject lo = new LikeObject( 10, 20 );
        added = lo.add();

つまり、このオブジェクトを作る際に、C言語ではライブラリ関数である malloc(3) を呼び出して、メモリを確保してキャストするが、オブジェクト指向言語では、この「新しくオブジェクトを作る」操作を言語レベルでサポートし、「new 演算子」によってメモリを割り当てる。それだけではなくて、「コンストラクタ」と呼ばれる、クラス名と同名の関数の「ようなもの」を同時に呼び出して「初期化」を行う(コンストラクタについては後で述べるが、先程の例だと LikeObject_init のような動作をするものである)。

また、C言語の時にはわざわざ引数として、確保された実体を渡さなくてはならない。しかし、オブジェクト指向言語では、「自分自身」を陰の引数として渡し、これを「this ポインタ」と呼ぶ。つまり、各オブジェクトごとに個別にそれを扱う関数がついている、といった雰囲気である。特にこういう関数をオブジェクト指向言語では「メソッド」と呼ぶ。LikeObject.add()LikeObject クラスのメソッドに当たる。

さて、C言語の例から見て、「構造体名」(LikeObject_tag)に相当するものを、オブジェクト指向言語では「クラス」と呼ぶ。つまり、具体的なオブジェクト(lo)を作り出す型紙のような働きをしていると考えれば良い。それに対して、具体的なオブジェクトとして生成されたものを「インスタンス」と呼ぶ。つまり、「new 演算子」によって、新たに「クラス」から「インスタンス」を生成すると考えれば良い。Java ではこの「クラス」さえも、「クラスオブジェクト」であり、「クラスオブジェクトのインスタンス」を生成できたりする辺りが面白い。



copyright by K.Sugiura, 1996-2006