クラスが持つ3つの役割

某所のチャットで話題になって、流れ去りそうだったのでもったいないから転載しておいた。事後承諾で。



MIYAMOTO Daisuke: 型の継承と実装の継承を区別する方法がないんだよな。

西尾泰和(nishio.hirokazu): 型を継承させずに実装を継承させたい→それ移譲で ってことかな?

MIYAMOTO Daisuke: そそ。そもそも、クラスに「型としての役割」と「実装としての役割」という複数の責務があることに、俺は長い間気づかなかった。これに気づかないと、型継承と実装継承が頭の中で整理できない。

西尾泰和(nishio.hirokazu): 僕が最近気づいたことも加えると、クラスには「ユーザ定義型」「インスタンスを作成する道具」「実装の再利用の単位」という3つの役割がある。

MIYAMOTO Daisuke: あぁ、インスタンスの生成器ね。

西尾泰和(nishio.hirokazu): 「型」って役割だけ取り出したのがJavaインターフェイスで、型の弱いスクリプト言語では「型」って役割がない分だけシンプル。Rubyはモジュールを「インスタンス作成」の機能がなくて「実装の再利用の単位」として扱うことで多重継承を分かりやすくしている

MIYAMOTO Daisuke: なるほど。Rubyはよく分かってないけど、なるほど。Javaのabstractクラス、も、インスタンスを生成する道具 という役割を放棄しているよね。

西尾泰和(nishio.hirokazu): なるほど。インターフェイスだけじゃないわけだ。そうかー、「型」って役割も兼ねているから複雑になるわけかー、なるほど。なんでスクリプト言語オブジェクト指向を学ぶと楽なのかちょっとわかった

MIYAMOTO Daisuke: うん、俺も「型の弱いスクリプト言語では「型」って役割がない分だけシンプル」ってのがピンと来た。↑トゥギャりたいなw


僕が最近気づいたって書いているのはTraitsの論文にクラスに「インスタンスを作成する道具」という役割と「実装の再利用の単位」という役割があり、この二つの役割は相反する、って書いてあったのがキッカケ。で、チャットで言われて気づいたけども静的型付け言語ではさらに「ユーザ定義型」という役割まであって、これももちろん「再利用の単位」としての役割とは必ずしもマッチしないわけよね。なのに再利用がしたいという理由で継承を使っちゃうケースが沢山あって、それでリスコフの置換原則だとかそういうのがよく言及されるようになったわけだ。

そういう意味では動的型付け言語にインターフェイスを入れるって発想はあながち悪くなかったのかも知れないなぁ。