Java では:
Base b = new Base();
Derived d = (Derived)b;
投げClassCastException
ます。なんで?Exception
ここでダウンキャストがスローされるのはなぜですか? 理由がわかりませんでした。
Java では:
Base b = new Base();
Derived d = (Derived)b;
投げClassCastException
ます。なんで?Exception
ここでダウンキャストがスローされるのはなぜですか? 理由がわかりませんでした。
わかりやすくするために、クラスの名前を変更させてください。 Base
-> Animal
. Derived
-> Cat
.
であるからといって、 であるとAnimal
は限りませんCat
。あなたはDog
. Animal
そのため、 anを aにキャストすることは違法Cat
です。
一方、すべてCat
はAnimal
? 答えは「はい」です。そのため、次のようなコードを記述できます。
Animal animal = new Cat();
また
Cat cat = new Cat();
Animal animal = cat;
また、注目に値するのは、これを行うことができることです:
Animal animal = new Cat();
Cat cat = (Cat) animal;
これができる理由は、animal
変数が実際にCat
インスタンスを参照しているためです。したがって、 を参照する変数にキャストし直すことができますCat
。
派生クラスを基本クラスとしてキャストすることはできません。またはb
として割り当てることができますが、としてのみ割り当てることができます。簡単に言うと、同じ型 ( ) または派生型の値として宣言された変数のみを割り当てることができます。Base
Derived
d
Derived
Base
Base
これで問題ありません (new
例として使用しているだけです。重要なのはデータ型です)。
Base b = new Base();
Base b = new Derived();
Derived d = new Derived();
しかし、これはそうではありません:
Derived d = new Base();
これが継承の仕組みです
派生クラスは、そのスーパー クラスから動作を継承します。したがって、派生クラス オブジェクトはスーパークラスによって定義された契約を満たすことができるため、サブクラス オブジェクトをスーパークラス参照にキャストすることは機能します。
一方、スーパークラス (クラスを定義する方法そのものによる) は、明らかにサブクラスに存在するほとんどのメソッドを実装していません。それが、最初にスーパークラスを拡張した理由です - その実装を拡張するためです。
したがって、スーパークラス オブジェクトをサブクラス型にキャストすることは、基本クラス オブジェクトがそのサブクラスの契約を完全に満たすことができないため、本質的に安全でない操作です。