最近作っている四則演算クラスは、ソースの見た目の個数を減らす為に、1つのソースファイルの中に複数のクラスを書いている。(その方が配布しやすいかと思った為。実際はアーカイブにしてるから関係ないかもー)
演算子クラスとルールクラスは数が増えたので、本当は別パッケージにして1ソース1クラスにしたい。
その場合、演算子パッケージとルールパッケージにして演算子・ルール毎に分けるのが一般的なのではないかと思う。継承関係はそれぞれの中で閉じてるしね。
が、密接に関わっているのは【演算子はいずれかのルールに属している】なので、加減算パッケージ、乗除算パッケージ…というように分けるという手も考えられる。そうすれば、例えばビット演算を削除したければ、そのパッケージを削除するだけなので分かり易い。
オブジェクト指向としてはどっちがいいんだろう?
strutsなんかもActionとFormを別パッケージにしているのをよく見かけるが、本当は画面とその操作はペアだし、画面の追加・削除は画面(ActionとFormの組)単位で行うわけだから、組をパッケージにするのが本来の姿ではないかという気がしないでもない。
ただ そうすると細かくなりすぎなので、HTML(jsp)のURIの階層ごとにパッケージにするのが一番無難かな?
まぁそれはそれとして。
ルールクラスと演算子クラスは、外部のプログラマーから使われたくないのでほとんどのメソッドをpublic以外にしているが、それぞれのクラスからお互いに呼び出したいメソッドがある。privateやprotectedにすると呼べないので、パッケージスコープにするしかない。
すると、そもそも別パッケージにできない!
C++みたいにメソッド毎にfriendを付けて、そのクラスからだけは呼べるように出来ればいいのに。
さらに気になるのは、protectedメンバーを見られる範囲。
注意深い入門書なんかには書いてあったと思うけど、同一ソースだか同一パッケージだか派生関係だかにある(←ちょー曖昧(爆))クラスのprotectedメンバーは、別インスタンスであっても参照できるんだよね。
僕のイメージでは、protectedは、継承先クラスの同一インスタンスからしか見えないんだけどなー。
そういう意味では、クラスの中に入れ子でクラスを定義すると 内側のクラスから外側のメンバーを参照できる(と思う)のも、けっこう妙な感じ。
あと、多重継承がしたいよー!
例えば代入演算子の「+=」。今回は「+」クラスから派生し、代入部分については「=」のクラスの代入メソッド(static)を呼ぶようにした。いわゆる委譲ってやつ?
昔から、ログ出力クラスとロジック本体クラスの両方から継承したい場面は多かった。
Javaの「インターフェース(interface)」は、そのクラスを使う側には便利だが、作る側にはちっとも優しくない。
ロジック本体を継承してログクラス用のインターフェースを実装することにすれば、外部から見た形式はちゃんとしてるけど、ログメソッドをいちいちコーディングする必要がある。それも大抵は外部のログクラスに委譲するので、そっちを呼ぶだけのコーディングがぽこぽこ出る。しかも、使わないものも書かないとコンパイルエラー。こんなの手間が増えるだけじゃ~ん!
「+=」が多重継承できたとすると、代入前の値の計算は「+」クラスのメソッドを使い、代入部分は「=」クラスのメソッドがそのまま呼べる。このメソッドでは計算結果の値だけ引数にすれば充分なはず。
Javaだとそれはできないから、委譲メソッドには変数のマップやらエラー時の位置やら、本来は隠しといて必要なときだけ使いたいようなものまで全部渡さなきゃならない…。
ところで多重継承してメソッド名が同一のものがあったら、どっちのスーパークラスが呼ばれるんだっけ? 親クラスを表すのはsuperしか無いし。
と一瞬思ったが、それはJavaでは1つのクラスからしか継承できないからsuperだけで済むのであって、C++では「親クラス名::メンバー」の形式で指定するから区別できるんだった(汗)
すっかりJavaに毒されてるなぁ(苦笑)
しかし、親クラス2つがさらに同じクラスから派生している場合、インスタンス変数はどうなるのか?という、C++に詳しい人ならよく知ってそうな話題は、やはり混乱の元。不便になろうがどうしようが無視して単純化したJavaでは、やっぱり多重継承は許さないという選択肢しかないんだろーなー。
※コメント投稿者のブログIDはブログ作成者のみに通知されます