30分で分かる!初心者からはじめる共変・反変講座
発端となったやり取り
共変戻り値がJavaにあってC#に無くてもC#でプログラミングができるのと同じ程度には、ほげほげがC#にあってJavaになくてもプログラミングできるんです。
2011-11-14 23:39:28@ufcpp ありますよ。複数レベルのインターフェイスを用意しておいて・・・とか、インターフェイスを介して使うときは見せることができないけど、クラスを直接使うときは見せたい(package privateの時によく使う)とか色々と
2011-11-14 23:45:44初心者のつぶやき
うーむ、勉強不足で用語の意味はよく分からないが、型Aの値を返すメソッドFを持つクラスXがあって、XのサブクラスYはメソッドFをオーバーライドしてAのサブクラスであるBの値を返すようにしたとき、上手くいくかどうか、ということなのかな…?
2011-11-14 23:57:02@bleis先生の共変・反変講座
@gab_km ですです。反変は逆で、継承したクラスでより弱い型を許可する感じ。Javaでできると思ってたけど、overrideじゃなくてoverloadだった模様
2011-11-14 23:59:55@bleis おー、なるほど。手続きを行う側の具体性を強めているのに、手続きの結果はより抽象的になっているのが、なんだか不思議な感じですね。
2011-11-15 00:04:06@gab_km 引数の位置で考えてみてください。継承前はより強い制約を求めているのに対して、継承したものでは制約を弱めることができます。リスコフの置換原則ですなー
2011-11-15 00:05:05@bleis おぉ、戻り値の型を制約としてみることができるんですね。Wikipedia http://t.co/tjvLU8p0 をチラ見してみたんですが、「戻り値は型A(またはその派生型)であること」というのが型Xに対して真になる属性=制約に当たるんでしょうか?
2011-11-15 00:14:17@gab_km そんな感じです。普通に考えると、戻り値の型としてAを要求する場所で派生型を返すのは問題ないですよね?なのでそれを型でも表せていいんじゃね?ってのが共変戻り値。
2011-11-15 00:17:42@bleis そうですね、共変についてはスッと入ってきます。さっきは戻り値で考えたから反変でしっくりこなかったんですが、引数の型で考えれば、こちらも分かりますね。
2011-11-15 00:21:31@cocoatomo先生の共変・反変講座
@cocoatomo はい、まさにその話です。あまりそういうことを意識したことがなかったので、ちょうどTL上で個人授業を受けているところです!
2011-11-15 00:18:46@gab_km あぁ, やっぱり. 自分は水が流れる方向が決まっているパイプを繋ぐときに,「入口はより広く, 出口はより狭くしないと水が溢れる」って感じで覚えていますよ.
2011-11-15 00:21:18@cocoatomo おぉ、なるほど!いま、リスコフの置換原則についてWikipediaを参照していたんですが、これに従わないと厄介な設計になるようですね。
2011-11-15 00:27:31@gab_km 例えば, Class.forName とかで自動で実装クラスを探して ClassLoader に読み込んだりするライブラリ (Logger 系で良く見る) の場合, リスコフの置換原則が破られると何が何だか分からなかったり, 置かれている jar によって酷い目に
2011-11-15 00:30:12@gab_km XML 系のライブラリだと日本語の扱いが残念なことがあって, 自動でダメな方をロードされるとかなり困りますね. なので, できれば動作とかも含めて置換原則は守られて欲しいですし, 継承はそれを守れる場合だけにして欲しいです.
2011-11-15 00:32:59