2010年7月18日日曜日

Cプログラマーから見たJava

私は、長くC言語(約20年くらい)プログラミングを行ってきました。当初、C言語は、CobolやFortranには無かった構造化設計が可能な上に、PL/IやPascalで可能であったポインタが利用できる点において、システム開発では有効であったと思います。(PL/Iは、コンパイラーが非常に重くIBMコンピュータでしか完全には利用できませんでしたし、Pascalでは、ビット演算など小回りの効くコーディングができなかったり、オブジェクトモジュール別の開発が面倒でした。)
その後、SmallTalkなどの成功によりオブジェクト指向プログラミングが流行るようになると、C言語でも同様の処理系が開発できないかと言うことが検討されC++が開発されました。しかし、C++を利用せずに、C言語でオブジェクト指向風のコーディングでできないかというアプローチも行われました。なぜ、オブジェクト指向プログラミングが大切かお話するまえに、C言語でオブジェト志向風プログラミングを行うコーディングにつてお話しましょう。これが、分かるとJava処理系の動作について分かるかと思います。

クラスには、インスタンスとメソッドがありますが、これは、C言語での構造体で定義します。インスタンスについては、構造体内の一般の変数、メソッドは、関数へのアドレスを格納します。

例えば、次のように書きます。
struct {
  int  instance;
  int  (*get_method)(void);
}  myClass;

instanceフィールドは、このクラスのインスタンス変数を格納するフィールドであり、get_methodフィールドは、get_method関数ポインターが格納されます。オブジェクト指向は、それぞれのオブジェクト毎に内部インスタンスとメソッドがありますが、このようにすることで、C構造体に付随するインスタンスとメソッドを定義します。あとは、この構造体を通じて、メソッドを通じて操作することでオブジェクト指向を実現します。

しかし、この構造体では、get_methodフィールドは、単に関数ポインターが格納されると宣言しているだけで、実際の関数アドレスが可能されている訳ではありません。そこで、これらの構造体に関数アドレスを事前に設定する必要があります。これらの初期設定する部分を関するにして、上記構造体のアドレスを返却する関数を以下のように用意します。
  myClass *handle = Create();

このCreate関数で、get_method関数アドレズを設定したります。このようにすると、次のように利用できます。
  thisValue =(* handle->get_method)();

Javaでもオブジェクトをクラスから作り出す際に、newオペレーターを使っていますが、内部的には、クラス特有に存在している構造体に、メソッド関数などを定義したり、各クラス内のインスタンス関数を実行しているものと思われます。この方法で、擬似的にオブジェクト指向風のプログラムを作成することができますが、クラスのインヘリタンス(継承)機能をC言語で記述することはできません。

0 件のコメント:

コメントを投稿