プログラミングに関わる身でありながら何となくで避けてきた「共変性」と「反変性」。例え話を考えて少しでも理解できるようにしたい!
例
とあるステーキレストランでは、ステーキセットとお子様ランチを料理(メニューという言葉は「出てくる料理」か「お品書き」なのかが分からなくなるため避けた)としている。レストランには接客、そしてお客様がいる。今回は簡単のためにコックは省略する。あるいはコックが接客を兼任しているとしよう。即ち:
今回の設定はこのような図に起こせる。
共変性
「お子様ランチを料理として扱う」ということになると思われるのだが、これはどういう時か。つまりこの図では「提供する」が該当する。味覚オンチのタキシードを着た客が「一番安い料理、それに調味料ありったけ」と注文して、お子様ランチが出てきても別に問題は無い。これは理解がそこまで難しいものではない。
反変性
共変性とは逆に「料理をお子様ランチとして扱う」わけだけど、どういうことだろうか。この図には無いので反則気味だが「料理を比較する」が当てはまる。料理を注文するとき、先ほどの銃みたいな剣を持った客みたいに値段はどうかとか、値段がカロリーに見合っているかとか、カロリー取りすぎじゃないかとか、いろいろ考えるわけだ。しかし、例えばステーキセットが「サーロインステーキ」「肩ロースステーキ」という風に分かれていても、(部位選びという新しい要素はあれど)根本的な料理の選び方は変わらないのではないか。
つまり「ステーキ選びも料理選びと要領が一緒だから、料理選びと同様にステーキを選んでも問題無いよね」というのが反変性だといえよう。
まとめ
反変性について少し分かったような気がした。でも継承は極力使わないけど。
JavaScriptとTypeScriptの関係も変性と言える。
TypeScript(上位互換)はJavaScript(下位互換)に変換できる。
これは共変性の好例である。
JavaScript(下位互換)は妥当なTypeScript(上位互換)である。
まさに反変性を表していると言えよう。