クラス型のキャスト
先日書いたようにキャストの仕様には腹が立っている。
1.プリミティブ型とクラス型で自動キャスト不可能方向が逆
逆なのだ。プリミティブ型では例えばint型変数(32bit)のデータをdouble型変数(64bit)に代入してもOK。
つまり小さいサイズのデータを大きいサイズの変数に入れるのは許可されるのだ。(自動的にキャスト宣言しているものとみなされるらしい。もちろん逆は不可。これはキャスト宣言しないといけない。)
一方クラス型の場合はスーパークラス(元のクラス)をサブクラス(extendsして作ったクラス)に入れる事は許可されない。extends(拡張)という用語から分かるように開発者もサブクラスのほうが大きいものと考えているにもかかわらずだ!(サブクラス型インスタンスをスーパークラス型変数に代入する事は許される。自動的にキャスト宣言に変換されてコンパイルされるらしい。)
どうやら、スーパークラスの方が内容が少ないから継承による増加分を無視すればいいので楽だから、という理屈らしい。確かにサブクラスのインスタンスがスーパークラス扱いされてもそうそう困る事はなさそうだが、逆は明らかにヤバイ。だからその辺は許してやろう。バグを防ぐにはそうするのが一番だから。
でもそんなら同じキャストって用語を使うなよ!紛らわしい!とか思ったが、それはつまり用語を増やせということで、それはそれで面倒そうだ。
だからそれはそれでいいのだ。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
2.アップとダウン
それよりも腹が立つのは「アップキャスト」と「ダウンキャスト」という用語のほうだ。
パッと見、アップの方がより高性能の方を指している様に思える・つまりスーパークラスのインスタンスをサブクラスにキャストしてる様に見えるが、実際は逆である。
┌────────┐ ┌────────┐ │スーパークラスa│←─(代入)──│サブクラスb │ └────────┘ └────────┘ アップキャスト(自動キャスト) ┌────────┐ ┌────────┐ │スーパークラスa│──(代入)─→│サブクラスb │ └────────┘ └────────┘ ダウンキャスト(要キャスト宣言)
なぜこの方向でアップ・ダウンというのか?妙ではないか!
英語でも
- 上位互換〔旧バージョンの視点から見た表現。旧バージョンのソフトで作成したデータが新バージョンでも読み込めるなど〕
=upward [upper, forward] compatibility
- 下位互換〔新バージョンの視点から見た表現。新バージョンのソフトが旧バージョンで作成したデータを読み込めるなど〕
=backward [downward, downwardly] compatibility
と書くのだから、明らかにUPは機能が上のもの=ここではサブクラスを指す、と考えそうなものだがJavaはそうではない。
実はこのアップ・ダウンキャストのネーミングは
┌──────────┐ │更にスーパーなクラス│ └─────┬────┘ │ ┌────────┴───────┐ │ │ ┌───┴────┐ ┌───┴────┐ │スーパークラスa│ │スーパークラスc│ └────────┘ └───┬────┘ ↑ │ (代入:アップキャスト) (代入:ダウンキャスト) │ ↓ ┌───┴────┐ ┌────────┐ │サブクラスb │ │サブクラスd │ └────────┘ └────────┘
こういう図が元になっているんだってさ。つまりスーパークラスがサブクラスの上にあるからなんだとよ。
バッカじゃネーの?図が元かよ。
じゃあもしかして「スーパー(超える)クラス」とか「サブ(下の)クラス」とかいうネーミングもそうなの?(個人的にはこれも印象が逆だ・・・。)おいおい!じゃあ、この図表形式って重要じゃん!でもどうせそれを強調してないんだろ。これに準拠しないでクラスの継承関係を左右に書いて説明する解説書もあるんだぜ!(逆引き早引きリファレンスJava:ASCII:2003年、は左から右に向けて継承関係を書いている。)こんなたまたま上から下に書いたから、といかいう理由でアップとダウンを決められたら、学習者はたまったものではないわッ!
既に下位互換
( downward compatibility )
って言葉があるんだから
そっちに合わせろよ!!
混乱の元だろうが!