アップキャストとダウンキャストは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
クラスでdogName();
メソッドを呼び出すのと同じ方法で、obj2が参照され、メソッドにアクセスできないため、PetDog
ダウンキャストobj2
する必要があります。PetDog
Dog
dogName();
( (PetDog)obj2).dogName();
なぜそうなるのですか、そのアップキャストは自動的ですが、ダウンキャストは手動でなければなりませんか?まあ、そうですね、アップキャストが失敗することはありません。あなたが別の犬のグループを持っており、すべてのタイプにそれらをダウンキャストしたい場合はしかし、その後、チャンスは、これらの犬のいくつかは、異なるタイプの実際にあること、あります、すなわちPetDog
、PoliceDog
、およびプロセスが投げることで、失敗しましたClassCastException
。
これが、オブジェクトをスーパークラスタイプに参照している場合に、手動でオブジェクトをダウンキャストする必要がある理由です。
注:ここで参照すると、オブジェクトをダウンキャストしたときにオブジェクトのメモリアドレスが変更されないということを意味します。この場合、オブジェクトの特定のタイプにグループ化しているだけです。 Dog
Dog
はAnimal
です。特定のオーバーロードメソッドを使用する場合を除き、ほとんどの場合、アップキャストは不要です。callme
両方に存在するAnimal
とDog
。callme2
はにのみ存在しDog
、機能させるためにキャストa
しますDog
。