Upcasting | Downcasting in Java

Table of contents

1. Upward transformation

direct assignment 

Summarize:

By passing parameters

by return value

2. Downward transformation

instanceof 


1. Upward transformation

Upcasting actually means creating a subclass object and using it as a parent class object. The general syntax format is as follows:

Paternal type Image name = new child type Category type()

Generally, there are three usage scenarios:

direct assignment 

We take the parent class as Animal class as an example, and there is a Cat classTo inherit him 

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);
    }
}

        In this case, we usethe parent class object to directly reference the subclass object. Not only will the program not report an error, but it will also work normally. Call the member method in the parent class

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

Output result: 

Can I call member methods of subclasses? We add a new sleep method in the subclass

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 + "正在睡觉......");
    }
}

We try to use the above process to call methods in the following subclasses:

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

But after we finish writing, we will find that the compiler reports an error 

That is to say:

After using upward transformation, we can call member methods in the parent class normally, but we cannot call our own methods in the subclass.

But it is still very simple to solve the above problem.When we override the parent class method in the subclass, we can call the subclass method< a i=2>, this is our polymorphic implementation

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();
        
    }

Now we can call the output normally:

Summarize:

When we create a new object through upward transformation, we can access the methods in the parent class through this object, but we cannot access our own methods in the subclass unless we override the parent class method in the subclass, that is to say, when Only if a method appears in both the parent class and the subclass, can we access this method in the subclass

Objects created through upward castThe range of methods that can be accessed is:

  • The parent class has it, but the subclass doesn’t.
  • The parent class has it, and the subclass has it too. 

The inaccessible range is:

  • The parent class doesn’t have it, and the subclass doesn’t have it either.
  • The parent class does not have it but the subclass does 

By passing parameters

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));

 We accept a parent class object through a method, and then call the eat method through this parent class object. When we pass in When the parameter is a subclass object, it is equivalent tothat we use the parent class object as a parameter to receive the subclass object, that is, an upward transformation occurs.

Output result:

by return value

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);
    }

We usethe parent class object as the return value type, but what we return is the subclass object , this is equivalent to an upward transformation

Advantages of upward transformation: Make code implementation simpler and more flexible.
Defect of upward transformation: methods unique to subclasses cannot be called 

2. Downward transformation

When a subclass object is used as a parent class method after upward transformation, the subclass method can no longer be called. However, sometimes you may need to call a subclass-specific method. In this case: restore the parent class reference to the subclass object. , i.e. downward conversion

 

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();
    }
}

 Output result:

instanceof 

Downcast is rarely used and is unsafe. If the conversion fails, an exception will be thrown at runtime. In order to improve the safety of downward conversion, instanceof  is introduced in Java. If the expression is true, it can be safely converted 

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;
    }
}

For detailed information about instanceof, you can check the official information:

 Chapter 15. Expressions (oracle.com)

 




Guess you like

Origin blog.csdn.net/m0_69519887/article/details/134358707