Revised: May/23rd/2004: Since: Dec./30th/2001
前節で見たとおり、参照型変数には、メモリ上の実態を参照するIDが代入されています。このような変数に対する参照の代入には、基本データ型には無い互換性の規則があります。
基本データ型の変数同士では、代入できる場合と出来ない場合がありました。拡張型変換ならば自動型変換されましたが、縮小型変換では明示的なキャストが必要でした。
参照型変数の代入とは、参照先を識別するIDのコピーです。参照型変数の場合は、同じクラス型であれば問題なく代入できますが、クラス型が異なれば代入できません。但し、継承関係にあるクラス型の場合は代入できる場合があります。
サブクラス型オブジェクトの参照は、スーパークラス型の変数に代入できます。自動的に型変換されます。
サブクラスはスーパークラスの定義を継承しています。このサブクラスをインスタンス化すると、スーパークラスで定義された部分に対するインスタンスも作られます。つまり、サブクラスのインスタンスには、スーパークラスの定義に対するインスタンスも含まれているのです。だから、サブクラスのオブジェクトを参照する変数はスーパークラス型変数に代入できます。
スーパークラス型オブジェクトの参照は、サブクラス型の変数には代入できません。一般に、スーパークラス型オブジェクトは、サブクラスで独自に実装している定義に対応するインスタンスを持たないからです。代入出来る場合でも、キャストが必要です。
スーパークラス型にサブクラス型の参照を代入することは頻繁に利用します。サブクラスでメソッドがオーバーライドされている場合は、スーパークラス型に変換されていてもサブクラスでオーバーライドしたメソッドの実装で動作しますから、これはとても便利な仕様だといえます。
Object
クラス一般に、クラス型変数は、その全てのサブクラス型変数と型の互換性を持ちます。全てのクラスはスーパークラスに Object
クラスを持つので、 Object
型変数は全てのクラス型の参照型変数と互換性を持ちます。但し、そこで利用できる機能は Object
クラスで定義された範囲に限ります。サブクラスで独自に定義したメソッドなどは、当該クラス型にキャストしないと利用できません。
MyClass myObj = new MyClass(); // スーパークラス型変数への代入 Object obj = myObj; // キャスト MyClass myObj2 = (MyClass)obj;
インタフェース型変数の場合も、クラス型変数と同じような互換性の規則を持ちます。クラス型変数は派生したサブクラス型変数からの代入互換性を持つと同様、インタフェース型変数の場合は実装クラス型変数からの互換性を持ちます。