インスタンスを参照するクラス型の変数も、整数のように型変換することができます。 ただし、まったく構造の異なるクラス型に変換することに意味は無いため、関係の無いクラス型に変換することはできません。 クラス型変数は、継承関係のあるクラス型に変換することができます。
サブクラスは、スーパークラスのメンバを継承しているため、スーパークラスのメンバの実装を保障していると考えることができます。 そのため、サブクラス型の変数をスーパークラス型の変数として利用しても問題はないのです。 この、サブクラス型からスーパークラス型への変換は暗黙的に行うことができます。
import std.stream; class A { } class B : A { } int main() { A objA = new B(); return 0; }
このプログラムでは A クラスを継承する B クラスのインスタンスを生成し、B クラスのオブジェクトを A クラス型の変数 objA に代入しています。 A クラスは B クラスのスーパークラスなのでオブジェクトの変換は暗黙的に行うことができます。 ただし、A クラスのオブジェクトをサブクラスの B クラス型に変換することはできないので注意してください。
A クラス型にオブジェクトを変換しても、インスタンスの情報が削られるわけではありません。 objA 変数が参照しているインスタンスは B クラスのオブジェクトであることに変化はありません。 そのため、objA を B クラス型の変数に変換することは事実上は可能ですが、A クラス型変数が B クラスのインスタンスであることを保障するものは何もありません。 下位クラスの型にオブジェクトを変換するには、明示的に cast() 式を使って変換しなければなりません。
import std.stream; class A { int value; } class B : A { int value; } int main() { A objA = new B(); B objB = cast(B)objA; objA.value = 10; objB.value = 100; stdout.printf("value = %d\n" , objA.value); stdout.printf("value = %d\n" , objB.value); return 0; }
このプログラムでは A クラスを継承する B クラスのインスタンスを生成し、参照を A クラス型変数 objA に保存してます。 この objA 変数を B クラス型の変数 objB にキャスト変換して代入します。 objA が参照しているインスタンスは A クラスを継承する B クラスのインスタンスなので、事実上、この参照は B クラスとして扱っても問題はありません。 しかし、サブクラスへの変換は暗黙的に行うことができないため cast() 式を使わなければなりません。
objA が参照しているインスタンスが B クラスのインスタンスかどうかは、コンパイル時に判断することができないため実行時に判定されます。 cast() 式を使っていても objA が B クラスのインスタンスでなければ実行時にエラーが発生します。