継承について。
「内包」「外延」「機能」
これらの違いをわきまえて、正しい設計を行いましょう、という話ですが、未だ私にはまだよくわかりません。特に機能と外延の違い。ソフトウェアの話に持っていこうとすると途端に区別できなくなります。 orz
[0回]
参考サイト。
継承に関わる諸問題結論としては、継承には「内包」を使うべき、ということになります。
これは他のサイトにも記述がありました。
ただ、どうしても自分の理解として落とし込むことができず、
めちゃくちゃ考え込んでしまいました。・・・まあ、今もそんなに解決したとは言いがたいのですが。
※今回のような「考える」きっかけを与えてくれたサイトのオーナー様(iwatamさんという方です)に感謝します。
(著作も出しておられるようですが、恥ずかしながら私は知りませんでした。サイトのコンテンツは非常に面白く興味深いものばかりなので、いつか読んでみたいなとは思ってます、、)
結局のところ、
私が納得できずに悩んでいた部分は
概念の内包・外延についての説明は読めばなんとなくわかったような気になるけれど、
じゃあオブジェクト指向としての「継承」とミックスしたらどういう話になるの?というようなことだったように思います。
「外延の継承」がどういうものなのか、というところが一番イメージしにくかったです。
内包=性質
外延=具象(具体的な1つ、またはそれらの集合)
であり、
ある概念の「内包」が充実すればその外延は乏しくなり、
ある概念の「外延」が充実していれば内縁についての記述は乏しくなる、
いわば反比例のような関係を持っています。
(上記は出典サイトがあったのですが、執筆時に見つけることができなかったために載せておりません。)
具体例を考えてみればこれは明らかだと思います。
「車」という概念について、
内包を
「駆動装置と車輪を持っており、人あるいは貨物を運搬できる能力を持つもの」
外延を
「トラック、軽四、バイク、(具体的な車種)、etc...」
とうように考えます。
内包を「...さらに、4つの車輪を持つ」と、少し充実させます。
一般には"四輪車"の内包、ということになりましょうか。
外延がどうなるかというと、とりあえず「バイク」は消えます。少なくとも先ほどの外延から集合の大きさは小さくなります。
今度は外延を充実させてみます。
「飛行機、船」
を加えてみましょう。
少なくとも、内包から「車輪」の部分は消えます。
現実世界ではこの概念は「乗り物」ということになりますね。
この場合、
「乗り物」->「車」という継承は自然な継承、「内包の継承」にあたります。
(というか、まずは概念ありきの内包/外延であって、上のような説明自体が本筋でない気もしますが。)
...で。
(ソフトウェア的な)継承とは
「オリジナルを受け継いで、オリジナル+αの新しいモノを作り出す」
ということです。
話をミックスすると、
>内包の継承
「ある概念の性質+α」の性質を持つ、新しい概念を生み出すこと
>外延の継承
「ある概念の具象物の集合+α(別な集合)」を持つ、新しい概念を生み出すことということになろうかと思います。
外延の継承について補足。
新しい派生概念は、継承前の概念よりも適応範囲が広い。
「これはβ(派生クラス)ですか?」
「これはα(基底クラス)ですか?」
という問いかけに対して、
βのカバー範囲(当てはまるモノの集合)はαのそれをぐいっと広げたものになっている必要があります。
「これはαです。でもβには当てはまりません」というようなのがあるようでは、外延の継承は破綻してると言うことになります。
現実世界のみの話であれば割とわかりやすいですが、
ことソフトウェアの話になりますと「車!」みたいに一言で説明できる概念ってそう多くないと思うんですよね。
だからイメージしにくい。話がややこしくなる。・・・のかな?と思います。私だけでしょうか。
継承前(親クラス)と継承後(子クラス)を見比べたとき、
「結局このクラスって何なのよ?」という問いを投げかけてみて、
親クラスより子クラスの方が説明が詳細であり、かつ具体的な現物をイメージしやすいようならそれは内包の継承。正しい継承と言って良いのではないか。
・・・と、まあこのように理解をしています。
このクラスはどんなクラスだ?とイメージしたときに、漠然としててコードレベル、実動作レベルでイメージがつかなかったものが、継承されていくにつれだんだんフォーマットやプロトコルなどの生データに近いイメージができるようになっていく。
こんな感じでしょうか。
機能の継承と外延の継承については違いがまだイマイチわかりません。
ひとまず私なりの理解はここまで、ということでひとまず締めくくろうと思います。
【投稿Log】
2012.6/19 (Tue) 投稿
PR