multiple inherit, mixin, delegate, implements
ふたたび D way の YT さんとこから。
is-a は継承で実現しろ、ってのが OO でよく言われる格言なわけですけど、じゃあ has-a で、かつその所有しているものを公開したい場合 (以下委譲と勝手に呼ぶ) は?というはなし。まとまった話はできそうにないので箇条書き。
委譲にはメソッド委譲とクラス委譲があります。と勝手に定義。
Java, D なんかでは一生懸命 private メンバを呼ぶだけのメソッドを作ります。メソッド委譲はそのメソッドのラッパを書く、クラス委譲はクラスのメソッド全てに対してラッパを書く。
=> めんどい。eclipse 無きゃ生きていけない人の気持ちがわかります。
C++, Eiffel は多重継承があるのでどうせ継承パスが余ってるからいいや、とクラス委譲は多重継承でやることがあります。
=> 「恐怖」の菱形継承。
Delphi はクラス委譲が interface への implements 指令という形でできる。YT さん教えて下さってありがとうございます。(http://hp.vector.co.jp/authors/VA028375/contents/delphipascal_oo_implements.html)
=> クラス委譲に関しては無問題?
Uva にはメソッド委譲の構文があります。(クラスもあったと記憶してたんだけど無かったみたい?) "forward to" (http://homepage1.nifty.com/CavalierLab/lab/uva/features.html#forward_to)
=> メソッド委譲に関しては無問題?
Ruby の Mixin でクラス委譲。(あれって Self あたりからの影響?よく知らない) 名前に関しては明確なルールがあるのでぶつからない。ただ Mixin できるのはクラスじゃなくてモジュールのみ。
=> 問題無いと思う。
Io は継承パスが強いのと弱いので二つあり、それらを適当に使えばなんとでもなります。
=> 動的な言語でないとどうにもならん。
ちなみにメソッド委譲には埋め込みというのもあるらしい。 (http://sumim.no-ip.com:8080/wiki/568)
この手の文法は GoF なんかでも必要性が謳われてるのにあまり実現されないのは何故。めんどいけどなんとかなる範囲だからかな。
D には Ruby or Delphi 的なクラス委譲と Uva 的なメソッド委譲があるといいなあ、ってとこかな。
で、 D にはメソッド委譲はまああるわけで、
class Func { void func() { stdout.writeLine("func"); } } class FuncKudasai { void delegate() func; Func funcObj_; this() { funcObj_ = new Func(); func = &funcObj_.func; } }
などと。まあ、
void delegate() func = &funcObj_.func;
と書きたいものですけど。
追記。 Delphi の implements と Ruby なんかの Mixin の比較がきちんとできてなかったんですけど、 YT さんがきちんと分析して下さいました。(http://hp.vector.co.jp/authors/VA028375/contents/delphipascal_oo_implements.html のミキシンとの比較という項を参照) なるほどねえ。ということは inline 展開できない、っていう小さな弱点が発生するわけですな…まあ D の delegate も inline 展開できないし整合は取れる。const 修飾子があればできるんだろうけどねえ…と、まだ無い機能に文句付けててもしかたないので誰か Walter 氏にくれくれって言ってきてください (人任せ) 。