Java--Polymorphism Upcasting and Downcasting

Polymorphism is also called dynamic binding , deferred binding or runtime binding . Quoting Charlie Calverts' description of polymorphism - polymorphism is a technique that allows you to make a parent object equal to one or more of its children , after assignment, the parent object can be assigned to its children according to the current assignment Traits work in different ways. Simply put, it is a sentence: it is allowed to assign pointers of subclass types to pointers of superclass types.

The cornerstone of polymorphism-- backward modeling :

interface Animal{    //动物接口
    void play(){};
}
class Dog implements Animal{    //狗类
    void play(){
        System.out.println("Dog");
    }
}
class Cat implements Animal{    //猫类
    void play(){
        System.out.println("Cat");
    }
}
public class Test{
    void play(Animal a){    //参数为动物接口
        a.play();
    }
    public static void main(String[] args){
        Dog dog = new Dog();
        Cat cat = new Cat();
        play(dog);    //传入狗类
        play(cat);    //传入猫类
    }
}

Why use upcast styling? Take the above code as an example. If you don't need to look up modeling, you need to write two play() methods in the Test class. The parameters are dog class and cat class. If the number of derived classes increases, the number of play() methods also increases. Using upcast modeling allows you to deal with the base class regardless of the derived class, which saves a lot of work.

Deep understanding of dynamic binding : The play() method of the Test class receives an Animal handle, so how does it know whether the handle points to Dog or Cat? This must be determined during runtime. So the binding performed before the runtime is called "early binding", and the binding performed at runtime is called "dynamic binding". Bindings of methods in Java are all dynamic bindings, unless a method is declared final.

The following statement also holds because of dynamic binding:

Animal a = new Dog();

Downstream modeling:

Upcasting will lose specific type information, so in order to obtain specific type information, "downcasting" can be used. However, upcasting is certainly safe; the base class can no longer have a larger interface than the derived class. Therefore, every message we send through the base class interface is guaranteed to be received. But it's not necessarily safe when doing downcast modeling.

class Useful {
    public void f() {}
}
class MoreUseful extends Useful {
    public void f() {}
    public void g() {}
}
public class RTTI {
    public static void main(String[] args) {
    Useful[] x = {
        new Useful(),
        new MoreUseful()   //上溯造型
    };
    ((MoreUseful)x[0]).g();    //下溯造型报错 Exception thrown
    ((MoreUseful)x[1]).g();    //下溯造型成功
 }
}

As shown in the above code, the derived class will lose data when it is backcast, but the data still exists after backcasting. The above code also means that downcasting is not necessarily safe.

Next Article: Abstract Classes and Interfaces of Polymorphism

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324438240&siteId=291194637