Skip to content.

Sections
Personal tools
You are here: Home » コミュニティ » masarl memorial » homepage3.nifty.com » masarl » article » nifty-logs » Niftyの過去ログ集 - 継承について

Niftyの過去ログ集 - 継承について

Document Actions

継承について

オブジェクト指向入門書によくある「継承」の説明について疑問に思ったことを投げかけてみました.

00399/00627 BYI20012  まさーる        継承について
(10)   96/07/13 23:27                     コメント数:4


みなさん、こんばんは。
継承についてみなさんの意見をお聞きしたいんですが...。

たとえば、最近の例だと

「車は乗り物である」

というのがありますよね?

このことから単純に車クラスは乗り物クラスのサブクラスと判断していいんだろ
うかということです。

なんというか、継承関係っていうのは上の例でいうと車と乗り物だけから決まら
ないものだ思うんですよね。

つまり、乗り物クラスを使う別のクラスがあってそのクラスからみて乗り物でさ
えあれば車だろうがなんでもいいや、ということが分かってはじめて継承を使う
んじゃないかと。

で、乗り物を使うあるクラスで乗り物の代わりに車をつかったら、動作がへんだ
ってことがわかればその継承関係は間違っているということになるし、そういう
クラスがみつからなければ正しいっていうことになると思います。

よーするに、ある継承関係が正しいかどうかっていうのはそれだけみててもわか
らないっていうのが僕の意見なんですが、みなさんはどう思います?

(ひょっとしたらすごく当たり前のことを聞いているのかもしれませんが、
入門ってことで許してください)

                                  96/07/13(土) 23:02 まさーる(BYI20012)

この発言は,ほとんどの方から賛同していただけました.ちょっと初心者の方から質問がありましたので,それについてレスしておきました.

00420/00627 BYI20012  まさーる        RE^2:継承について(長文)
(10)   96/07/16 14:08  00417へのコメント  コメント数:1

桜 さん、はじめまして。

桜さんがおっしゃられていることは、全面的に正しいと思います。でも、僕の言
いたかったこととは違います。

オブジェクト指向初心者とのことですが、C言語などの経験はあるでしょうか? 
ここでは勝手に経験があるとして説明しますね。

さて、C言語の構成要素は基本的に関数です。桜さんは関数をつくるときどうい
うふうにしてますか? たとえば、似たような処理が所々ある、ここはまとまっ
た処理だから1つにしておいた方がよい、という理由で関数をつくることも多い
かと思います。

けれども、プログラムを書いている途中、こういう処理をする関数があればいい
な、と思ってとりあえず関数のプロトタイプだけ決めておいてからっぽの関数を
作る、という場合もありますよね。そしてあとから中身を書くと。

このとき、このプログラムを書いている側からみれば、この関数が実際にどうい
うふうに処理を実現しているかは問題じゃなくて、関数のインターフェイスだけ
を問題にしているわけです。とりあえず関数の実装を無視できるぶん、複雑さを
軽減できたといえます。

そして、あとから中身を書く場合、インターフェイスをちゃんと満たすようにか
かないとそれはバグになりますよね。


以上のことをふまえて、今度はオブジェクト指向で考えてみます。

さて、クラスをつくるときどういうふうにしているでしょうか? 先ほどの関数
の場合と同様、まとまった部分があれば、それを1つにしてクラスにしたり、今
まで使っているクラスをちょっとの修正で再利用できるものがあればそれを継承
してクラスにしたり...という感じでしょうか。


でも、やっぱりプログラムを書いているときに、こういうクラスがあればいいな、
という仕様だけ決めておいて次に進める場合もありますよね。

このとき、さっきの関数の例との対応で、

        関数のインターフェイス  <--> スーパークラス
        関数の中身              <--> サブクラス

というふうに考えてみます。すると、プログラムを書いている側からみると、ス
ーパークラスがどういうものか、ということだけが問題なのであってサブクラス
はこの際どうでもよい、と思えるわけで、より詳細なサブクラスの情報を無視で
きるぶん、複雑さを軽減できたといえます。

さらに、継承の場合はこのサブクラスを動的に変えることもできるし、スーパー
クラスとサブクラスをそれぞれ別々のライブラリに入れておくこともできるし、
関数の場合よりもかなり強力です(関数の場合でも関数ポインタをつかえばでき
んことはないですが)。

これが、継承のもつもう一つの利点なわけで、このことを最大限に利用している
のがアプリケーションフレームワークです。フレームワークのデベロッパはユー
ザがどういう具体的にどういうアプリケーションをつくるのかを無視して、クラ
スライブラリを組むことができるわけです。

で、継承関係を考える場合は、この点を重視しないと失敗するのではないか?
というのが僕の趣旨です。本来のスーパークラスのインターフェイスに沿わない
サブクラスをつくってしまったら、それは間違いだし、バグです。


>私たちがソフトウェアを作る場合、必ずしも知り尽くしている領域を扱うとは限りませ
>ん。この場合、はじめから的確なクラス構成ができるとは限らないことになります。
>やはり、何度も吟味され、書き直されて、ようやく一人前(?)のクラスにしていくしか
>ないのでしょうか?

面倒ですが、していくしかないのでしょう。

>それとも、デザインパターンなどを読めば少しは解消されますでしょうか?
>(まだ、はじめの数ページしか読んでないのですが・・・(^^;)

デザインパターンやパターンランゲージの最先端がどうなっているのか僕も知り
ませんが、いわゆる建築の世界のパターンランゲージの完成度からは程遠いとい
う印象をうけます。
でも、デザインパターンの本をよめば確かにフレームワークなどの構成が頭に入
りやすくなるし、拾い読みもできる本なのでぜひ読んでみてください。

>「乗り物クラス」からは、「トラッククラス」「バスクラス」「バイククラス」な
>んかも作れそうですが、「乗り物クラス」に1トンの荷物を積もうとしても無理が
>あるような気がするし、人を30人詰め込もうとしても無理があるような気がしま
>す。
>(「乗り物クラス」って、なんか抽象クラスになりそうな気がしますが・・・)
>では、「乗り物クラス」と「車クラス」の継承関係が間違っているのでしょうか?

この場合は、1トンの荷物を積むというメソッドや30人詰め込むというメソッド
を乗り物クラスに加えたのがまちがいなのでしょう。これらは「トラッククラ
ス」や「バスクラス」特有のメソッドと考えたらどうですか。すくなくとも、乗
り物クラスにあるすべてのメソッドを「トラッククラス」や「バスクラス」がち
ゃんとフォローする必要があります。


>もともと、今まで書いてきたことがまさーるさんのいわんとされていることとは違
>うのかもしれません。でも、「乗り物クラス」と「車クラス」の継承関係が間違っ
>ているようには思えないし、また、「乗り物クラス」で「車クラス」の代用もでき
>ないと思うのですが、間違っているのでしょうか。

継承関係があるなら、「車クラス」は「乗り物クラス」のインターフェイスをも
つ、ということはお分かりいただけましたでしょうか。すると、車クラスのイン
スタンスは乗り物クラスをあつかうプログラムに対しても適用できます。


>うだうだと書いてしまいましたが、お許し下さい。
>初心者でも許されるようでしたので、発言してみました。

いえいえ、桜さんの発言はとっても好感がもてましたです。もっと初心者の方々
が発言しやすくなると会議室のタイトルから(仮称)がとれるかも。

#それとも「ファミ通のあれ(仮題)」みたいにずっとこれで通すのかな?


                                     96/07/16(火) まさーる(BYI20012)

なんか Open-Closed Principle の初心者向け解説みたいな感じです.この説明考えるのにかなり苦労した記憶が(^^;.でも今見るとそんなに大した説明でもないですね.