言語仕様とオブジェクト指向
Mixinとアスペクト指向
Mixin(またはMix-in)は1980年代のLisp系オブジェクト指向システムFlavorsで登場した機構で、最近の言語ではRubyに実装されています。Rubyはクラスに付け加えられる機能の集合をモジュールという単位で定義し、これを該当するクラスでインクルードすることでMixinを実現します。Mixin自体はクラスではありません。
例えば、Rubyの組み込みモジュールにComparableというものがあります。2つのオブジェクトを比較する演算子「」を定義しているクラスであればこのモジュールをインクルードすることができ、それによって比較演算子==や
Mixinと同様、継承ではうまく実装を共有できない場合を取り扱うという目的が共通しているので、ここでアスペクト指向プログラミングについて少々説明をします。ただし、アスペクト指向はオブジェクト指向ではありません。
オブジェクト指向でプログラムを作成すると、例えば、オブジェクトをシリアライズする機能、ログ機能などは、継承とは無関係にさまざまなクラスでばらばらに実装されることがあります。オブジェクト指向の考え方ではうまく表現できず、実装が散在してしまう事柄を、アスペクト指向では「横断的関心事」と呼びます。
アスペクト指向言語(あるいはフレームワーク)では横断的関心事をアスペクトと呼ぶコードとして記述し、既存のプログラムに追加(ウイービング)することができます。アスペクト指向の考え方自体は、既存のプログラミング概念を相補するという意味でオブジェクト指向とは直交すると説明されることが多いようです。
オブジェクト指向の本質
さてオブジェクト指向言語とは何なのでしょうか。オブジェクト指向言語としての要件として、最近は、継承、カプセル化、ポリモーフィズムをあげるのが一般的です。まず継承について考えてみましょう。
継承は概念間の包含関係を利用して対象をクラス分けすることで、コードを記述すべきクラスと再利用するクラスの関係を半ば自動的に決める巧妙なメカニズムとして機能します。この仕組みは大抵うまく機能するため、クラス階層をプログラミングの中心的な仕組みとして採用している言語が多いのです。このような言語をクラスベースのオブジェクト指向言語と呼びます。
ただし、クラス階層内で実装を共有しない場合、インタフェース継承やデリゲートでクラス継承の代用とすることは可能です。
また、クラスが存在しない、あるいはインスタンスの生成に必ずしもクラスが必要ではない言語もあり、プロトタイプベース、あるいはインスタンスベースのオブジェクト指向言語と呼ばれます。このタイプの言語では、すでに存在するオブジェクトの複製(クローン)を作ることによって、新しいオブジェクトを作り出し、同時に継承も実現します。典型的な例がJavaScriptです。
次にカプセル化ですが、この概念は継承機能のない手続き型言語にも存在します。カプセル化されたモジュールの集合としてソフトウエアを記述する言語をモジュール指向言語と呼ぶことがあります。また、オブジェクト指向言語の前段階と評される抽象データ型言語では、実体のデータとそれに対する演算を一体化して新しいデータ型を定義しますが、実装はカプセル化されています。これらの言語には、Pascalの後継言語である Modula2や初期のAdaなどがあります。
つまり、カプセル化とクラス階層には直接の関係はなく、クラス階層内で共有される実装に対して詳細なアクセス制御を行おうとすると、第3回(http://www.thinkit.co.jp/article/158/3/)で紹介したように面倒なことになります。
クラス階層を基本として型チェックを行う言語では、ポリモーフィズムもクラスと密接に関連しているように見えます。ただし、型チェックはインタフェースに対してのみ行われますので、実装が共有されている必要はありません。また、そもそも静的な型付けではなく、オブジェクトの動的な性質に基づいてポリモーフィズムを実現しているSmalltalkやRubyのような言語もあります。
ただし、クラス階層を利用した抽象メソッドとポリモーフィズムの組み合わせは、いくつかのデザインパターンにおいて劇的な効果をもたらします。第2回(http://www.thinkit.co.jp/article/158/2/)で示した図形クラスはその単純な例ですが、この効果がもたらす成功体験こそが、現在のオブジェクト指向言語の全盛をもたらしていると言っても過言ではないでしょう。
このように見てくると、オブジェクト指向言語とは何かという問いに言語仕様の面から答えるのは、実は逆に極めて困難であることがわかってきます。オブジェクト指向とは結局のところ、「情報交換しながら動作する複数のオブジェクトというモデルに基づいたプログラミングを支援する機能を備えた言語」という説明になります。
クラスベースのオブジェクト指向言語と言い直すと、もう少し言うべきことが出てきます。モデルに内在する概念間の関係を、型階層および実装の共有の手段として利用しているという点と、同じ概念グループに属する異なる実装をポリモーフィズムによって統一的に扱うという点です。
モデル化において、オブジェクトは人間の認識に近い「見立て」の手段として利用されます。さらにオブジェクト指向プログラミングを利用することによって、その見立てをUML図からプログラムコード、実行中のメモリの中にまで一貫したものとして持ち込むことができるようになりました。子供がただの木片を自動車に見立てて楽しく遊ぶように、プログラマはいくつかのデータと手続きを「会員」や「利用履歴」であると見立て、組み合わせてシステムを構築するのです。
多少哲学的に言うと、オブジェクト指向言語とは「見立て」がプログラム上でも維持されるようにサポートする仕組みなのです。
本連載では、オブジェクト指向言語を言語仕様の側面から紹介しましたが、基本的な部分はざっと見て回れたのではないかと思います。対象が漠然としているので、いまひとつ焦点が定まりにくい部分があったかもしれませんが、言語の違いによって考え方が違う部分などを楽しんでいただければ幸いです。
オブジェクト指向はそもそも基本用語の意味にすら共通認識のない無法地帯です。万人が納得する解説文を書くのはそもそも不可能ですので、多少の違和感はご容赦ください。
最後になりましたが、「言語を何か勉強するとしたら?」と聞かれたら、個人的には、まずはC言語を勉強することをおすすめします。まだ習得していない方はぜひチャレンジしてみてください。
なお、本稿の執筆にあたって、以下を参考にしました。
まつもとゆきひろ『まつもと直伝 プログラミングのオキテ 第3回(3)(http://itpro.nikkeibp.co.jp/article/COLUMN/20050915/221232/)』(アクセス:2008/11)
米山学『アスペクト指向のバリエーション解説 第1回 アスペクト指向の基礎とさまざまな実装(http://www.atmarkit.co.jp/farc/rensai/aspect01/aspect01.html)』(アクセス:2008/11)
Jonathan Rees『Re: OO(http://practical-scheme.net/trans/reesoo-j.html)』(アクセス:2008/11)
前橋和弥『疑りぶかいあなたのためのオブジェクト指向再入門(http://kmaebashi.com/programmer/object/)』(アクセス:2008/11)
あきみち『プログラマがC言語を学ぶべき10の理由(http://www.geekpage.jp/blog/?id=2006/11/27)』(アクセス:2008/11)