アップキャストとダウンキャストは Java の重要な部分であり、単純な構文を使用して複雑なプログラムを構築することを可能にし、ポリモーフィズムや異なるオブジェクトのグループ化などの大きな利点をもたらします。Java では、サブクラス タイプのオブジェクトを任意のスーパークラス タイプのオブジェクトとして扱うことができます。これをアップキャストと呼びます。アップキャストは自動的に行われますが、ダウンキャストはプログラマーが手動で行う必要があります。その理由を説明するために最善を尽くします。
アップキャストとダウンキャストは、プリミティブをあるものから別のものにキャストするようなものではありません。プログラマーがオブジェクトのキャストを学び始めると、それが多くの混乱を引き起こすと思います。
ポリモーフィズム: Java のすべてのメソッドは、デフォルトで仮想です。つまり、そのメソッドが final または static として宣言されていない限り、継承で使用される場合、任意のメソッドをオーバーライドできます。
以下の例でgetType();
は、オブジェクト (犬、ペット、警察犬) の種類に応じてどのように機能するかを確認できます。
あなたが3匹の犬を飼っているとします
犬 - これはスーパー クラスです。
ペットの犬 - ペットの犬は犬を拡張します。
警察犬 - 警察犬はペット犬を拡張します。
public class Dog{
public String getType () {
System.out.println("NormalDog");
return "NormalDog";
}
}
/**
* Pet Dog has an extra method dogName()
*/
public class PetDog extends Dog{
public String getType () {
System.out.println("PetDog");
return "PetDog";
}
public String dogName () {
System.out.println("I don't have Name !!");
return "NO Name";
}
}
/**
* Police Dog has an extra method secretId()
*/
public class PoliceDog extends PetDog{
public String secretId() {
System.out.println("ID");
return "ID";
}
public String getType () {
System.out.println("I am a Police Dog");
return "Police Dog";
}
}
ポリモーフィズム: Java のすべてのメソッドは、デフォルトで仮想です。これは、そのメソッドが final または static として宣言されていない限り、継承で使用されるときに任意のメソッドをオーバーライドできることを意味します。(説明は仮想テーブルの概念に属します)
仮想テーブル / ディスパッチ テーブル : オブジェクトのディスパッチ テーブルには、オブジェクトの動的にバインドされたメソッドのアドレスが含まれます。メソッド呼び出しは、オブジェクトのディスパッチ テーブルからメソッドのアドレスをフェッチすることによって実行されます。ディスパッチ テーブルは、同じクラスに属するすべてのオブジェクトで同じであるため、通常はオブジェクト間で共有されます。
public static void main (String[] args) {
/**
* Creating the different objects with super class Reference
*/
Dog obj1 = new Dog();
` /**
* Object of Pet Dog is created with Dog Reference since
* Upcasting is done automatically for us we don't have to worry about it
*
*/
Dog obj2 = new PetDog();
` /**
* Object of Police Dog is created with Dog Reference since
* Upcasting is done automatically for us we don't have to worry
* about it here even though we are extending PoliceDog with PetDog
* since PetDog is extending Dog Java automatically upcast for us
*/
Dog obj3 = new PoliceDog();
}
obj1.getType();
版画Normal Dog
obj2.getType();
版画Pet Dog
obj3.getType();
版画Police Dog
ダウンキャストは、プログラマーが手動で行う必要があります
階層内のスーパークラスであるが参照されているメソッドを呼び出そうとすると、メソッドにアクセスできないため、エラーがスローsecretID();
されます。そのメソッドを呼び出すには、obj3 を手動でダウンキャストする必要があります。obj3
PoliceDog object
Dog
obj3
secretId()
PoliceDog
( (PoliceDog)obj3).secretID();
印刷するID
obj2 が参照され、メソッドにアクセスできないため、ダウンキャストする必要があるクラスでdogName();
メソッドを呼び出すのと同様の方法でPetDog
obj2
PetDog
Dog
dogName();
( (PetDog)obj2).dogName();
アップキャストは自動であるのに、ダウンキャストは手動でなければならないのはなぜですか? アップキャストが失敗することはありません。しかし、異なる Dog のグループがあり、それらすべてをそれぞれのタイプにダウンキャストしたい場合、これらの Dog の一部が実際には異なるタイプ、つまり 、PetDog
でPoliceDog
あり、 をスローしてプロセスが失敗する可能性がありますClassCastException
。
これが、オブジェクトをスーパー クラス タイプに参照している場合に、オブジェクトを手動でダウンキャストする必要がある理由です。
注:ここでの参照とは、オブジェクトをダウンキャストするときにオブジェクトのメモリアドレスを変更していないことを意味します。この場合、オブジェクトを特定のタイプにグループ化するだけです。Dog