実はオブジェクト指向ってしっくりこないんです?

――いや、自己分析するに、「オブジェクト指向」ではなく「特定のオブジェクト指向プログラミング言語」がしっくりこないことがあるんだな、これが。

具体的には、触ったことのある言語ではJavaC#だ。この2つの「しっくりこなさ」具合からすれば、C++の方がマシだ(もっとも、C++は別の部分で好きになれない面があるのだが*1)。

C#は経験が浅すぎるので、Javaについて。Javaは、ここ数年の間にちょっとしたコンソールアプリの実装とAndroidアプリの開発で使用した。興味深いことに、コンソールアプリを書いた際は「しっくりこなさ」全開だったのだが、Androidアプリを書いた時にはその手の違和感はなかった。

この違いは何だろうと考えて、ふと気づいた。おそらく私は、クラスの定義を強要されることに違和感を感じる体質なのだ。

私のプログラマとしての土台(第一プログラミング言語)はC言語だ。C言語にはクラスはない。次に使うことが多いC++は、クラスを定義するも定義しないも活殺自在な言語だ。JavaScript/JScriptVBScriptも、クラスを定義する/しないは比較的自由だ。小ツール実装で時々使うRubyPythonは、ちょっとしたスクリプトであれば構文の見た目として「クラス定義なんて知らないよっメソッド定義だけだよ!」風に記述できる。

これらの言語のうち、C言語C++のアプリケーションメインエントリは関数だ。JavaScript/JScriptVBScriptRubyPythonでは、必須構文としてのアプリケーションメインエントリ的なものはない*2

つまり、C言語を除けば、コードの見た目として「必要になったらクラスを定義するが、必要なければ使わない(関数/メソッドを単独で定義して用いる)」というスタイルで記述することが可能な言語に慣れている(そしてC言語にはそもそもクラスが存在しない)。

しかしJavaC#は、例えばC++にてmain関数と2つのサブ関数で記述できるような小ツールであっても、クラスを定義した上でmainメソッドを記述しなくてはならない。この時点で、何というか「この程度のことでクラスを持ち出すなんて……」と思ってしまうのだ。

その一方で、Androidアプリのような複雑な*3ソフトウェア、特にGUIアプリケーションというオブジェクト指向プログラミング的アプローチに向いているソフトウェアでは、クラスを用いる意味もメリットもあるので、違和感を感じることがない。とはいえ、時としてクラスに属しないメソッドを書きたくなることはある。C++ならば名前空間に直接属する関数として、Objective-CならC言語流のファイルによるモジュール分割を用いたデータ結合の関数として定義するだろう、ちょっとした汎用のユーティリティ・メソッドだ。

別の視点から考察すると、どうも私は「構造体(=レコード型)」の影響を強く受けていて、「何らかの関連がある複数のデータ+それらを操作する専用のルーチン=オブジェクト」という意識が強い。C言語で構造体を使用してややオブジェクト指向プログラミングっぽいアプローチをすることもあるが、その場合、「何らかの関連がある複数のデータ」を一まとめにする必要があるならば構造体にまとめるが、必要なければまとめない。

つまり、心理的に「クラス≒抽象データ型≒レコード(複数のフィールド)と操作用ルーチン」という意識がある。抽象データ型として扱うのが妥当ならばクラスにするが、それ以外の用途――例えばJavaJavaScriptのMathクラスのような使い方――でのクラスの採用に消極的というか、クラス以外の代替機能を使おうとする個人的傾向がある。

仮にMathクラスのようなものをC++で再実装するならば*4、個人的にはクラスではなく名前空間を使用して、関数や定数をひとまとめにするだろう。

このようなアプローチは、例えばC++で採用するには問題ない。しかし、慣れ故にJavaC#でも採用しようとしてしまい、メソッドをクラス内でしか定義できないことに気づき、ついついもやもやしたものを感じてしまう。

現実には、プログラミング言語には「言語仕様」という制約がある訳で、その制約の元では、例えば「『C++名前空間』のような機能がないので、代わりにクラスを使う」などのアプローチは合法的だろう。だから、もやもやしたものを感じてしまう必要など全くないのだが……。

結局のところ、慣れの問題なのだ。クラスのない世界での生活が長く、また必要に応じてクラスを定義するか否かを切り替えられる言語に慣れてしまっていて、クラスが必須な言語には慣れていないので、違和感を感じるのだろう。

蛇足:クラスが必須な言語に違和感を感じる一方で、CやC++のような関数が必須な言語(ステートメントを関数の中にしか記述できない言語)には違和感を感じないあたり、どう考えても慣れの問題以外の何者でもない。

*1:好きにはなれないが、better Cとして使い方をわきまえている分には便利な言語だと思う。

*2:もしかしたら、私が知らないだけで、アプリケーションメインエントリ的なものがあるかもしれない。しかし、そうだとしても、必須ではない(何らかの構文として記述する必要がない)だろうから、その言語のユーザからすれば「無いも同然」だ。

*3:テキストフィルタよりもGUIアプリの方が複雑だ、という意味での「複雑な」である。

*4:標準ライブラリに用意されている、C言語由来のcmathの数学関数は無視するものとする。