>その論理で行くと、マルチプロセスやマルチスレッドはオブジェクト指向になると
>思いますが、
ならないと思いますが……
まあ、オセロの例で注記したように、マルチプロセスにはオブジェクト指向と似た面は
ありますけど。「その論理で行くと」の「その論理」がどういう論理か、教えて
いただきたいです。
>例えばこれを修正して、大文字に変換して返す物を使いたいとします。
>-----------------------------------------------------------
>public class UpperStack extends Stack {
> public String get(){
> return super.get().toUpperCase();
> }
>}
>-----------------------------------------------------------
774RRさんがすでに書いていますけど、これは典型的な「ダメな実装継承の例」でしょう。
# 「実装継承」でGoogleしてみることをお勧めします。
実のところ「要素を大文字に変換して返すスタック」がどんな時に役に立つのか
想像できませんが、それはまあ、「あくまで例だから」ということにしても、
このケースは、
「要素をgetする側は、大文字が欲しいとき、そのことを意識している」
のでしょうか。
意識しているのであれば、そもそも「stack.get().toUpperCase();」で済む話です。
大文字に変換する、という単純な処理でないのなら、ユーティリティメソッドを
作ればよいでしょう。
そこでわざわざ継承してクラスを作ったって、以下のような問題が起きるだけです。
・Stackが引数かなにかで渡されたとき、本家StackなのかUpperStackなのか
わからなくて危険。
・別の誰かがLowerStackを作ったら、いつかマージするの?
・ユーティリティメソッドではprivateメンバにアクセスできないが、
継承なら、protectedにしておけばサブクラスからアクセスできる、というのが
趣旨なら、それはカプセル化の破壊以外の何者でもない。
ところで、SEさんの例では、get()メソッドがオーバーライドされています。
「要素をgetする側は、大文字が欲しいとき、そのことを意識している」のであれば、
仮に継承を使うとしても、getUpper()メソッドをつけることでしょう。
オーバーライドしているということは、
「要素をgetする側は、大文字が欲しいとき、そのことを意識しないで済む」
ということにしたいのでしょうか?
# それにしては、get(boolean up)と対比しているのでよくわかりませんが。
もしそうなら、
>そのため、変更により以前の機能のまま使用したい場所には影響がありません。
というわけにはいきません。
この改修により、プログラムにUpperStackという「異物」が実行時に紛れ込むわけで、
「Stackにputしたんだから、当然同じものがgetできるだろう」と思い込んでいる
既存コード(Stackそのものを含む)にはおもいっきり影響を与えます。
しかも、get(boolean up)とは違い、実際に動かしてみなければ検出できない
バグになりますからさらにタチが悪いです。
上のほうで『実のところ「要素を大文字に変換して返すスタック」がどんな時に
役に立つのか想像できません』と書きましたが、結城浩さんが「例は嘘をつかない」
と書いておられるように、こういうところで現実のプログラムに即した適切な例が
出てこないなら、おそらくそれは考え方のほうが間違っています。
ひとつ伺いたいのですが、SEさんはどんな本でオブジェクト指向の勉強をされたの
でしょうか。
いまどきこんなバリバリの実装継承でオブジェクト指向を説明している教科書は
そうそうないと思っていたので、もし新しい本にそういうことが書いてあったのなら
興味があります。ぜひ書名を教えてください。
ところで、私が現在作っているクラスベースオブジェクト指向言語Diksamでは、
「concreteクラスは継承できない」ということにしてしまっています。これは
実装の手抜きではなく、意図して行っています。
ここまでやってしまうと異論はあるかもしれませんが、Effective Javaとか
GoFのデザパタ本とかで、かなり昔から、散々「抽象クラス以外は継承するな」と
言われてますし、SEさんのような誤解を防止するためにもこの方がよいのではないかと。
http://java-house.jp/ml/archive/j-h-b/050862.html