1. ホーム
  2. java

[解決済み] クラス変数に関するアップキャスティングとダウンキャスティングの違いを教えてください。

2022-03-02 03:25:57

質問

クラス変数に関するアップキャスティングとダウンキャスティングの違いは何ですか?

例えば、次のプログラムでは、Animalクラスにはメソッドが1つしかありませんが、Dogクラスには2つのメソッドがあります。

もし、キャスティングが行われた場合、Animalの変数でDogの別のメソッドを呼び出すにはどうすればよいのでしょうか。

class Animal 
{ 
    public void callme()
    {
        System.out.println("In callme of Animal");
    }
}


class Dog extends Animal 
{ 
    public void callme()
    {
        System.out.println("In callme of Dog");
    }

    public void callme2()
    {
        System.out.println("In callme2 of Dog");
    }
}

public class UseAnimlas 
{
    public static void main (String [] args) 
    {
        Dog d = new Dog();      
        Animal a = (Animal)d;
        d.callme();
        a.callme();
        ((Dog) a).callme2();
    }
}

解決方法は?

アップキャスティングはスーパータイプへのキャスト、ダウンキャスティングはサブタイプへのキャストです。アップキャストは常に許可されますが、ダウンキャストは型チェックが行われ ClassCastException .

あなたの場合 DogAnimal はアップキャストであるため DogAnimal . 一般に、2つのクラスの間にis-a関係がある場合は、いつでもアップキャストすることができます。

ダウンキャストは、こんな感じでしょうか。

Animal animal = new Dog();
Dog castedDog = (Dog) animal;

基本的に、あなたがしていることは、オブジェクトの実行時の型が何であるかを知っていることをコンパイラに伝えることです。 本当に です。コンパイラは変換を許可しますが、変換が意味をなすかどうかを確認するために、実行時のサニティチェックを挿入します。この場合、キャストが可能なのは、実行時に animal は、実際には Dog の静的な型であっても animalAnimal .

しかし、仮にこうすると

Animal animal = new Animal();
Dog notADog = (Dog) animal;

を取得することになります。 ClassCastException . なぜかというと animal のランタイム型は Animal そのため、ランタイムにキャストを実行するように指示すると animal は実際には Dog を投げるので ClassCastException .

スーパークラスのメソッドを呼び出すには、次のようにします。 super.method() またはアップキャストを実行することで。

サブクラスのメソッドを呼び出すには、ダウンキャストを行う必要があります。上に示したように、通常は ClassCastException を使用することができます。 instanceof 演算子でオブジェクトの実行時型を確認してからキャストを行うことで、そのオブジェクトの ClassCastException s:

Animal animal = getAnimal(); // Maybe a Dog? Maybe a Cat? Maybe an Animal?
if (animal instanceof Dog) {
    // Guaranteed to succeed, barring classloader shenanigans
    Dog castedDog = (Dog) animal;
}

ダウンキャストは、Java 16以降、より簡潔に表現できるようになり、次のようなものが導入されました。 のパターンマッチングを行います。 instanceof :

Animal animal = getAnimal(); // Maybe a Dog? Maybe a Cat? Maybe an Animal?
if (animal instanceof Dog castedDog) {
    // now castedDog is available here as in the example above
}