Java でのアップキャスト | ダウンキャスト

目次

1. 上向きの変革

直接割り当て 

要約:

パラメータを渡すことによって

戻り値による

2. 下方変革

インスタンスの 


1. 上向きの変革

アップキャストとは、実際にはサブクラス オブジェクトを作成し、それを親クラス オブジェクトとして使用することを意味します。一般的な構文形式は次のとおりです。

父类类型 对象名 = new 子类类型()

一般に、次の 3 つの使用シナリオがあります。

直接割り当て 

例として、親クラスを動物クラスとします。猫クラスもあります。 彼を継承するには 

class Animal {
    String name;
    int age;
    //构造方法
    public Animal(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃食物~~~");
    }
}
class Cat extends Animal {
    //构造方法
    public Cat(String name,int age) {
        super(name,age);
    }
}

        この場合、親クラス オブジェクトを使用してサブクラス オブジェクトを直接参照します。プログラムはエラーを報告しないだけでなく、親クラスのメンバー メソッドを呼び出します

    public static void main(String[] args) {
        Cat cat = new Cat("布偶",3);
        Animal animal1 = cat;
        animal1.eat();
        
        Animal animal2 = new Cat("橘猫",2);
        animal2.eat();
    }

出力結果: 

サブクラスのメンバーメソッドを呼び出すことはできますか?サブクラスに新しい sleep メソッドを追加します

class Animal {
    String name;
    int age;
    //构造方法
    public Animal(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃食物~~~");
    }
}
class Cat extends Animal {
    //构造方法
    public Cat(String name,int age) {
        super(name,age);
    }
    //新添加的子类方法
    public void sleep() {
        System.out.println(this.name + "正在睡觉......");
    }
}

上記のプロセスを使用して、次のサブクラスのメソッドを呼び出してみます。

    public static void main(String[] args) {       
        Animal animal = new Cat("橘猫",2);
        animal.eat();
        animal.sleep();   
    }

しかし、書き終えた後、コンパイラがエラーを報告していることがわかります。 

つまり、次のようになります。

上向き変換を使用した後は、親クラスのメンバー メソッドを通常どおり呼び出すことができますが、サブクラスで独自のメソッドを呼び出すことはできません。

しかし、上記の問題を解決するのはまだ非常に簡単です。サブクラスで親クラスのメソッドをオーバーライドすると、サブクラスのメソッドを呼び出すことができます。< a i= 2>、これはポリモーフィックな実装です

class Animal {
    String name;
    int age;
    //构造方法
    public Animal(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃食物~~~");
    }
    public void sleep() {
    }
}
class Cat extends Animal {
    //构造方法
    public Cat(String name,int age) {
        super(name,age);
    }
    public void sleep() {
        System.out.println(this.name + "正在睡觉......");
    }
}
    public static void main(String[] args) {
        
        Animal animal = new Cat("橘猫",2);
        animal.eat();
        animal.sleep();
        
    }

これで、出力を通常どおり呼び出すことができます。

要約:

上方変換を通じて新しいオブジェクトを作成すると、このオブジェクトを通じて親クラスのメソッドにアクセスできますが、サブクラスで親クラスのメソッドをオーバーライドしない限り、サブクラスの独自のメソッドにはアクセスできません。メソッドが親クラスとサブクラスの両方に存在する場合にのみ、サブクラスでこのメソッドにアクセスできます。

上向きキャストによって作成されたオブジェクトアクセスできるメソッドの範囲は次のとおりです:

  • 親クラスにはそれがありますが、サブクラスにはありません。
  • 親クラスにもそれがあり、サブクラスにもそれがあります。 

アクセスできない範囲は:

  • 親クラスにはそれがありませんし、サブクラスにもそれがありません。
  • 親クラスにはそれがありませんが、サブクラスにはあります 

パラメータを渡すことによって

class Animal {
    String name;
    int age;
    //构造方法
    public Animal(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃食物~~~");
    }
}
class Dog extends Animal {
    //构造方法
    public Dog(String name,int age) {
        super(name,age);
    }
    public void eat(){
        System.out.println(this.name + "正在吃狗粮~~~");
    }
}
class Cat extends Animal {
    //构造方法
    public Cat(String name,int age) {
        super(name,age);
    }
    public void eat(){
        System.out.println(this.name + "正在吃猫粮~~~");
    }
}
    public static void fun(Animal animal) {
        animal.eat();
    }
fun(new Dog("哈士奇",2));
fun(new Cat("橘猫",2));

 メソッドを通じて親クラス オブジェクトを受け入れ、この親クラス オブジェクトを通じてeat メソッドを呼び出します。パラメータがサブクラス オブジェクトである場合、サブクラス オブジェクトを受け取るパラメータとして親クラス オブジェクトを使用することと同等、つまり上向きの変換が発生します。

出力結果:

戻り値による

class Animal {
    String name;
    int age;
    //构造方法
    public Animal(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃食物~~~");
    }
}
class Dog extends Animal {
    //构造方法
    public Dog(String name,int age) {
        super(name,age);
    }
    public void eat(){
        System.out.println(this.name + "正在吃狗粮~~~");
    }
}
class Cat extends Animal {
    //构造方法
    public Cat(String name,int age) {
        super(name,age);
    }
    public void eat(){
        System.out.println(this.name + "正在吃猫粮~~~");
    }
}
    public static Animal fun1(Animal animal) {
        return new Cat("布偶",3);
    }
    public static Animal fun2(Animal animal) {
        return new Dog("哈士奇",2);
    }

戻り値の型として親クラス オブジェクトを使用しますが、返すのはサブクラス オブジェクト 、これは上方変換に相当します。

上向き変換の利点: コードの実装がよりシンプルかつ柔軟になります。
上方変換の欠陥: サブクラスに固有のメソッドを呼び出すことができません 

2. 下方変革

上方変換後にサブクラス オブジェクトを親クラスのメソッドとして使用すると、サブクラスのメソッドを呼び出すことができなくなります。ただし、場合によっては、サブクラス固有のメソッドを呼び出す必要がある場合があります。この場合は、親クラスの参照をサブクラスに復元します。オブジェクト、つまり下方変換

 

class Animal {
    String name;
    int age;
    //构造方法
    public Animal(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃食物~~~");
    }
    public void sleep() {
    }
}
class Cat extends Animal {
    //构造方法
    public Cat(String name,int age) {
        super(name,age);
    }
    public void sleep() {
        System.out.println(this.name + "正在睡觉......");
    }
}
public class Test_4 {
    public static void main(String[] args) {
        Animal animal = new Cat("橘猫",2);
        Cat cat = new Cat("布偶",2);
        animal.eat();
        animal.sleep();
        cat = (Cat)animal;
        cat.eat();
        cat.sleep();
    }
}

 出力結果:

インスタンスの 

ダウンキャストはめったに使用されず、安全ではありません。変換が失敗すると、実行時に例外がスローされます。 Java では、下方変換の安全性を高めるために、 instanceof  が導入されており、式が true であれば安全に変換できます 

public static void main(String[] args) {
    Cat cat = new Cat("元宝",2);
    Dog dog = new Dog("小七", 1);
    // 向上转型
    Animal animal = cat;
    animal.eat();
    animal = dog;
    animal.eat();
    if(animal instanceof Cat) {
        cat = (Cat)animal;
    }
    if(animal instanceof Dog) {
        dog = (Dog)animal;
    }
}

instanceof の詳細については、公式情報を確認してください。

 第15章 式 (oracle.com)

 




おすすめ

転載: blog.csdn.net/m0_69519887/article/details/134358707