宣言classとコンストラクタの所属



 お待たせしました。不定期連載再開です。


 さて。
 まず俺の先入観を一つ披露させてもらおうか。

インスタンスの生成では
宣言クラス名コンストラクタ名
でなければならない

この思い込みが粉々に砕かれたのは忘れもしない・・・えーっと・・・・そうそう20070613の記事だった。ここで参考にしたソースコード

    Frame w = new Mouse1();

というのが有って、ビックリしたのだ。wの型名がFrameなのに対してコンストラクタの名前がMouse1(ファイル名)なのだ!違ってもいいんだナ、これ。
 まあ、Mouse1はFrameをextendsして作ったクラスなので不可能では無い→Frameのコンストラクタをオーバーライドして生成する事を許可する、という事なのだろう。
 という事は逆(Mouse1 w = new Frame();)は許されないということだろうか?

Mouse1.java:31: 互換性のない型
検出値  : java.awt.Frame
期待値  : Mouse1
    Mouse1 w = new Frame();
               ^

 やっぱりダメだった。前者は互換性があるという事はコンストラクタの方(つまりextendsされた方のコンストラクタ)には上位互換性(後発のシステム(上位)が先発のシステム(下位)からの生成物を扱えること)があるということか。まあ、当然といえば当然だな。
 しかし

※眠いので以下書きかけ状態でUPして寝る。
もういくらでも罵倒のコメントをしてくれ。
眠いのだー。つづきはあすー。

翌日追記:
さっそくnori氏のコメントが得られた。

> Frame w = new Mouse1();

これは、クラスMouse1をインスタンス化した後、Frame型にアップキャストしているということですね。なぜこんなことするのかは不明ですが…。上の文は、

Frame w = (Frame)(new Mouse1());

と同じですね。コンパイル後のクラスファイルを比較してみたところ、完全に一致しましたので間違いはないと思います。

 成る程。実験感謝する。そうかこれはキャストなのか。

ところで、6/13のソースはバグありのようです…(笑)

 うむ。

mainThread.end++; //いつかオーバーフローするが気にしない。

長期実行時には間違いなく異常が起こると思われる(フフニヤリ)。

 キャストのことは、つい先日まで僕もいまいちよく理解できてませんでした。アップキャストというのは下位クラスから上位クラスにキャストすることで、ダウンキャストというのは上位クラスから下位クラスにキャストすることなんですけど、通常、問題がないとされるのはアップキャストのほうなんですよね。ダウンキャストは問題が生じることが多いです。

 ふ〜む。この辺は俺の実験と一致するな。

ちなみに、ダウンキャストというのは、本来は「アップキャストしたものを元に戻すために使われる」そうです。
http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000107.html

 たとえば、String型をObject型にアップキャストした後に、再びString型に戻すのはOKということですね。

 おお!このサイトは分かり易い!全体にちゃんと日本人が読んで分かるように書いてある。当たり前のようだが、そこんとこが重要。早速サイドバーのリンク集に追加。

ダウンキャストでは、渡される参照の値や、その参照が指し示すインスタンスは全く変化しない。変わるのは、参照を格納する、参照型変数の見かけ上の型だけである。

 これは要注意だ。そしてそうでないとツジツマが合わない。extendsした方で定義した変数が読まれなくなってしまうからだ。


 しかし
「ダウンキャスト」=「アップキャストを元に戻すこと」
であるならば、「ダウン」じゃ対等の操作に見えてしまって良くない。
ここは「アンアップキャスト」とでも命名するべきだったな。
これなら”初めにアップキャストありき”と分かるだろ。
インストールする前にアンインストールできないようにな。


 ところで、そもそもこの「キャスト」の命名と仕様についても腹を立てているのだが、それはまた別のお話。



                                                                                      • -

 ところで20070618の記事で、swingの自動ダブルバッファを実現するために、それまでのextends JFrame をextends JPanel に変えたわけだが、内部で生成しているJFrameインスタンスはそのまま流用、という状況で、ちょっとおかしい印象を受けた。


 何がおかしいのかというと

    JFrame frame = new JFrame();

でフレームを生成しているのに、そのフレームにマウスイベントが装備されていることなのである。だってマウスイベントを設定しているのはextends JPanel された Graph8_2 クラスなんだぜ?じゃあ何かい?このGraph8_2 クラス内部で生成されたFrameやJFrameのフレームはすべて自動的にマウスイベントが実装されちゃうのぉ?
「所属クラスで宣言されたアダプターは問答無用に生成されたインスタンスに装備されるのか?」(これが二週間前の予告の具体的な内容)


 と、思ったがどうやら

    frame.getContentPane().add( new Graph8_2() );

で、フレームのコンテントペインに元のクラスのインスタンスを追加しているようだ。(しかしこの技、無条件に使っていいのかなぁ・・・使いようによってはバグの原因になりそうで怖い。しかも複雑に入り組んで別の意味でスパゲッティプログラムになりそう。)
 しかし相変わらずContentPaneが何なのかイマイチよく分からん。コンテナを乗せるモノだというのは良く聞くが抽象的な解説では分からん!具体的にどういうデータを扱ってるのかとかが無いぞ。APIは言うまでも無く役立たずだし。


 と言うわけで、予告の内容は半分で終わり。あとの半分は上記のように不発で終わった。


俺のマヌケぇぇぇぇぇッ!!