- - PR -
class or interface ?
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-09-01 13:49
乗り物の例で言うと, 乗り物を使って目的地につくためにはドライブだけでなくて いろいろなメソッドをつかうわけです. 例えば現在位置を特定したり, また現在位置から目的地にいたるルートを特定したり といったことです. それらのメソッドを組み合わせて目的地に着くわけですが, そのメソッドを使う 手順のことをここではプロトコルと勝手に呼びました. (ちょっと勝手にそう呼んでしまったのはまずかったかと思いますが) このようなことが常にできるわけではありませんが, これもまたオブジェクト指向 と呼んで良い物と考えます. 現在のjavaの仕様とそれほどかけ離れたことを考えているわけではないと思います. | ||||||||
|
投稿日時: 2003-09-01 13:54
つまり、指示の受け渡しの関係は 運転手 <-> コンピュータ <-> 乗り物本体 のようになっているわけですよね。 運転手 <-> コンピュータ間は目的地の指示だけで、 コンピュータ <-> 乗り物本体間では実際のハンドル操作等のやり取りが行われると。 このように、問題領域(ドメイン)を抽象度や機能の固有性などをもとに分割することを 「レイヤリング」と呼び、分割された各部分を「レイヤ」と呼びます。 レイヤリングの基本は、あるレイヤに依存する対象を 隣接するレイヤに限定することです(レイヤリングにおけるカプセル化)。 すなわち、上の例で言うと、「運転手 <-> コンピュータ」と「コンピュータ <-> 乗り物本体」間の やり取りの規約(=広い意味でのインターフェース)は独立していなければならないということです。 しかし、Junさんの例では、「運転手 <-> コンピュータ」のインターフェースがpublicメソッド、 「コンピュータ <-> 乗り物本体」のインターフェースが非publicメソッドとして混在することに なってしまいます。 このようなやり方は、レイヤ間の独立性を大きく損ねるものだと思いませんか? # ちなみに「レイヤリング」の失敗は、大抵の場合、大きな手戻りの発生や # ソフトウェアの保守性の低下など、深刻な悪影響を引き起こします。 まとめると、 (1)interfaceに非publicなメンバの宣言も認める メリット: 複数のレイヤ間の(広い意味での)インターフェースを一つのファイルに記述できる。 デメリット: 本来独立したものであるはずの複数のインターフェースを 一つの(Javaの)interfaceとして宣言することは、レイヤリングの原則に反する。 (2)interfaceにはpublicメンバしか認めない メリット: アクセス制限が一つしかないため、一つの(Javaの)interfaceに 一つの(レイヤ間)インターフェースを記述することが自ずと強制される。 デメリット(?): レイヤリングの原則を無視するような記述ができない。 根拠は上に示したとおりです。 もしJunさんの意見が、 「レイヤリングやカプセル化の原則に反していようとも、 Javaのinterfaceに非publicなメンバを記述できる自由が プログラマに与えられるべきだ」 というものでしたら、もはや私には反論する気はありません。 # でも、そういうのはC#とかでやってほしいなあ… [ メッセージ編集済み 編集者: yamasa 編集日時 2003-09-02 15:28 ] | ||||||||
|
投稿日時: 2003-09-01 14:57
こんにちは。なんかJunさんの主張って変です。
:Javaのインターフェースのたとえ 電源アダプタとは、次のようなものである 1.形状が・・・・であること。 2.電圧や周波数が・・・・のとき、正しく動作すること。 :Junさんのインターフェースのたとえ 電源アダプタとは、次のようなものである 1.同上 2.同上 3.コンデンサはA社のものを使うこと 4.抵抗はB社のものを使うこと 5.電源安定化の部分はこの回路図を用いること 6.アースの部分はこの回路図を用いること こういった内部のあれこれについて制約される規格は、だれも使わないと思います。 同様に、内部の実装方法について制約を受けるインターフェースも使いにくいと思います。もしこのようなインターフェースが存在すると、 class JPanel extends JComponent implements ImplementLikeThis1, ImplementLikeThis2 ..... ImplementLikeThis100 とかになって、内部実装の仕方を変更できなくなってしまいます。悲劇です。 [ メッセージ編集済み 編集者: ocean 編集日時 2003-09-01 15:02 ] | ||||||||
|
投稿日時: 2003-09-01 17:45
私の言っているのは全体で完結した(内部を意識することのない)クラスを提供しよう ということであってその内部の構成については作成者側で把握しているのですから それの制約を使用者側では意識する必要がないのです. それを拡張して使うということは考えていないのです. だから内部実装の仕方を変更できないのは悲劇でなく, それが目的だといっているのです. | ||||||||
|
投稿日時: 2003-09-01 18:16
とのことですが、インターフェースは外部に公開されてしまっているので、 ImplementLikeThis1[] a = { new JPanel() }; といったコードが存在する場合、内部実装の変更(ImplementLikeThis1をやっぱりやめたとか)がコンパイルの失敗を招きます。ですので、使用者側でも意識せざるを得ません。java.util.RandomAccessはカテゴリを示す働きをしますが、Junさんのおっしゃるものとはやはり違う気がします。 [ メッセージ編集済み 編集者: ocean 編集日時 2003-09-01 18:36 ] | ||||||||
|
投稿日時: 2003-09-01 18:22
つまり、あなたによるあなたのためのインターフェイスなのですね。 自分でインターフェイスを定義し、自分で実装クラスを作成する。 そして、インターフェイス型を他の人が参照することもない。 そういう目的ならば、package private(publicでない)インターフェイスと 実装クラスを定義することをお勧めします。 ちなみに、乗り物とコンピュータの例でコンピュータを乗り物(の実装クラス)の サブクラスとして定義するのは、明らかにおかしいですよ。 A Computer is a kind of Vehicle.じゃないでしょ。 | ||||||||
|
投稿日時: 2003-09-02 08:39
コンピュータはサブクラスでなく私の例で言うとプロトコルに相当しますが | ||||||||
|
投稿日時: 2003-09-02 08:48
ですから本当はprotectedでなくprivateにしたいのだといったのです でもprotectedでも出来上がったクラスをfinalにしてしまえばいいかな と思っています. |