[???] /
[Java FAQ] / [S014]
S014: 型 - type
[S014-Q01]
なぜスーパークラス(またはインタフェース)の型の変数に代入するのですか?
[S014-A01]
複数の異なるクラスのオブジェクトを同じクラス(インタフェース)の
オブジェクトとして扱えるためです。
一つ目の例では、画面コンポーネントを一つの配列に代入しています。
--
Component[] components = new Component[3];
components[0] = new Button();
components[1] = new TextField();
components[2] = new Label("Hello");
--
Button, TextField, Label はともに Component のサブクラスなので、
Component 型の変数に代入することができます。すると、
これらを Component 型のオブジェクトとして統一的に扱うことが
できるようになります。
--
for (int i = 0; i < components.length; i++) {
System.out.println("name = " + components[i].getName());
}
--
次の例では、任意のリスト(java.util.List)を引数として、
そのリストを逆順にする次のようなメソッドを考えてみます。
void reverse(List list) { ... }
List はインタフェースなので、直接のインスタンスを作成することはできませ
んが、こうすることによって List を実装(implements)する任意のクラスのイン
スタンスを引数として渡すことができます。
--
Vector v = new Vector();
...
reverse(v);
--
ArrayList al = new ArrayList();
...
reverse(al);
--
など。
また、reverse メソッド内では引数として与えられたオブジェクトが、Vector
であろうが ArrayList であろうが、List インタフェースが実装されているクラ
スのオブジェクトであれば何でも扱うことができます。
参考記事[JavaHouse-Brewers:6749],[JavaHouse-Brewers:6707]
[S014-Q02]
cast 演算子が不要なときというのはどんなときですか?
[S014-A02]
ある変数を cast するときに、cast 演算子(*)が必要かどうかは、
以下のルールによります。
(*)型名を括弧書きで表す型変換演算子:
例 String str = (String) obj; の "(String)" の部分
(1) primitive型の場合は次のルールに従います
(変換前と変換後が同じ型の場合は省略しています)。
変換前の型 変換不能 cast演算子必要 cast演算子不要
boolean すべて
byte boolean char short/int/long/float/double
char boolean byte/short int/long/float/double
short boolean byte/char int/long/float/double
int boolean byte/char/short long/float/double
long boolean byte/char/short/int float/double
float boolean byte/char/short/int/long double
fouble boolean byte/char/short/int/long
(2) 参照型の場合は、
o 変数が表すクラスの親のクラス
o 変数が表すクラスが実装するインタフェース
に cast する場合には cast 演算子はいりません。
たとえば次の例で、Hashtable は Dictionary を継承して、
Map を実装していますから、cast する必要はありません。
--
Hashtable h = new Hashtable();
Dictionary d = h;
Map m = h;
--
しかし、上記以外の場合は cast が必要です。以下のような場合は
cast が必要となります(例は上記の続きです)。
--
Hashtable h2 = (Hashtable) d;
Dictionary d2 = (Dictionary) m;
参考記事[JavaHouse-Brewers:10597]
[S014-Q03]
配列型を扱うときの問題点はなんですか?
[S014-A03]
あるクラスを配列クラスにしたとき、そのサブクラスの配列を代入することができます。
--
Object[] array = new String[10];
--
ところが、array は Object[] 型なので、その要素(array[0]など)は
Object 型となり、Object のサブクラスの代入が記述できてしまいます。
--
array[0] = new Integer(1);
--
しかし、これはコンパイルは成功しますが、実行時に
ArrayStoreException が発生します。
--
参考記事[JavaHouse-Brewers:23523]
contributor: markn
コメントの送り先 Java FAQ BBS