クラスと型
クラスから型の側面をズバッと切り離すと、
- オブジェクトのファクトリ
- オブジェクトの処理の移譲先
と言う風になると思います。(特定言語圏の話かもしれないけれど)
* * *
クラスベースな OOPL の場合、オブジェクトは自身にメッセージが送られども、実際自分でそれに対する処理を出来るわけでは無くって、クラスに処理を委譲してやってもらいます。クラスベース オンリーなOOPLの場合オブジェクトが自前でメソッドを持つのは禁則事項です♪ になるわけです。こういう意味ではオブジェクトファクトリ(生みの親)であるクラスを「母」と喩えれば子はみんな臑齧り。「おかーさん、コレやって」「おかーさん、あれやってー」・・・なんだか凄く不健全な気がしてきたョ orz...
プロトタイプべースな OOPL の場合、オブジェクトは処理を委譲しないで自力で解決可能になります。値と同じようにメソッドもオブジェクトが持つことが出来るからです。この文脈では上記で列挙したクラスの責務と同等のことを実現するオブジェクトを作るのは容易です。要するに「子はやがて親になる(こともできる)」というわけです。カッコイイー (けれどここまで来るとちょっと喩えが強引すぎる気が(^^; )。
ここまでの説明では、プロトタイプベースの説明との対比のために、意図的にクラスが特殊なオブジェクトであるような書き方をしています。が、これは処理系によりけりで「オブジェクトがクラスに委譲する」なんてコードは存在しないトコの方がむしろ多いかも。「存在しないトコ」では「オブジェクトがクラスに処理を委譲」は、単なる一つのたとえ話に過ぎません。
こういった場合、オブジェクトが事実上 操作を持っていないクラスベースオンリーな世界として、オブジェクトをデータ、クラスを型と見なせば おなじみの型システムで 世界が上手く回っちゃいます。「クラス指向」などと揶揄される側の OOP がコレです。
ただ、だからといってそれの延長線上に、全ての「型」や「クラス」、「オブジェクトが直にメソッドを持つこと」を捉えると、いまいち美味しくないのです。
* * *
さて、ここらへんで、そもそも型とはなんなのかという話をクリアしましょう。単純に言えば 型とはデータの種類であり、「○○型とは何か」は そのデータに対する行うことができる操作の集合 で定義されます。
コンピュータにとっては 操作とデータが可分であるので、本来そのデータに対し行うことが出来ない操作を強引に行うことは出来ます。するとどうなるか・・・は、C と戯れられるような方は重々ご承知のことだと思います。ここで大事(?)なのはやってやれないことはないと言うことです。――たとえその結果コアダンプを吐こうとも...。 だから、絶対成り行きに任せちゃダメで、ちゃんとチェックしてブロックしないとヤバいのです。*1
というわけで、普通の処理系はあるデータに対してこの操作をやったらヤバいか? をやっちゃう前にチェックしてくれます。これをコンパイル時に予見してブロックするか、実行時に発見してブロックするかの戦略は、その言語次第。だから、
{"one":1}.lengthといえば、「lengthなんてプロパティはありません」と怒られる
404 Blog Not Found:タイプ・クラス・プロトタイプ - OOの語彙
と怒られるのは、ちゃんと型チェックされているということです。
* * *
型という語でイメージする「何かのくぼみ」と、そこに当てはめることが出来る「モノ」があったとき、その外形が「型」――というメタファは、私は かなり正しいモノじゃないかな、と思ってます。
そのくぼみにモノをはめることが出来るかを判ずる際に、「当てはめる前にあらかじめ予見する」のも「当てはめてみて填らなかったら諦める」のも、両方とも型チェックには違いないです。
(一般的な)静的型付けは、変数に型を持たせちゃうことで モノが生まれた瞬間からそのくぼみに当てはまるのかを判ぜざるをえない風にして、あとは連鎖的に数独を解くかのように詰めていく仕組みです。しかし、ある型とある型の境界は曖昧で、「データAは○○型!データBは××型!!」と、生まれたときからキッチリ決めてかかることは メリットだけでなくデメリットも孕んでいます。デメリットが我慢ならない、という人の為の動的型付けで、「とりあえずやってみる」はその「とりあえず」な印象とは裏腹に有効な手段です。
なにはともあれ、そこに明示的な型宣言がなくとも、当てはめる「何かのくぼみ」と当てはめたい「モノ」があれば、そこに「型」は確かに存在する。そんな単純なお話でした。
(うまくまとまらなかかったです。嘘かいてないといいなぁ)
余談(または蛇足)
型つながりで斜め上の話題へジャンプ。
こと OOP 界隈では、クラスは型なのか? という問題は、特に継承がらみで なかなかモヤモヤなので 難しいところだと思います。(あたしもこんな「解った風な」エントリ書いといて、なのに全然もやもやのまっただ中です)
継承とクラスと型の話については、odzさんの解りやすい説明 が一番オススメですが、私の冗長なやつ(↓)も読んでくれるとうれしいです。(←目立ちたがりなのです)
*1:無いハズのものに豪快に清々しくアクセスしてみせる「型無し」だとか、「弱い型付け」とか言われている言語だってあるわけです。(T△T