Speeding up and downgrading is an important part of Java, which allows us to create complex programs using simple syntax and gives us great advantages, such as polymorphism or grouping of different objects. Java allows an object of a subclass type to be processed as an object of any type of superclass. This is called a boost. Activation is done automatically, while downcasting must be done manually by the programmer , and I'm going to give my best to explain why this is so.
Upcasting and downcasting are not like casting primitives from one to the other, and I think this causes a lot of confusion when a programmer begins to study cast objects.
Polymorphism: all methods in java are virtual by default. This means that any method can be overridden when used in inheritance, if this method is not declared as final or static .
The following is an example of how getType(); works according to the type of object (Dog, Pet, Police Dog).
Suppose you have three dogs
- A dog is a superclass.
- Pet Dog - Pet Dog expands Dog.
Police Dog - A police dog expands a dog.
public class Dog{ public String getType () { System.out.println("NormalDog"); return "NormalDog"; } } 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"; } } 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"; } }
Polymorphism: all methods in java are virtual by default. This means that any method can be overridden when used in inheritance, if this method is not declared as final or static. (Explanation refers to the concept of virtual tables)
Virtual table / dispatcher table. The object dispatch table will contain the addresses of the dynamically linked methods of the object. A method call is made by extracting the method address from the object dispatch table. The distribution table is the same for all objects belonging to the same class, and therefore is usually distributed between them.
public static void main (String[] args) { Dog obj1 = new Dog(); ` Dog obj2 = new PetDog(); ` Dog obj3 = new PoliceDog(); } obj1.getType();
Print Normal Dog
obj2.getType();
Seal Pet Dog
obj3.getType();
Fingerprints of Police Dog
Downside must be done manually by the programmer
When you try to call the secretID(); method secretID(); to obj3 , which is a PoliceDog object , but referencing Dog , which is a superclass in the hierarchy, it throws an error because obj3 does not have access to secretId() . To call this method, you need to downcast that obj3 manually, PoliceDog
( (PoliceDog)obj3).secretID();
which prints ID
Similarly, to call dogName(); in the PetDog class, you need to compress obj2 in PetDog , since obj2 refers to Dog and does not have access to the dogName(); method dogName();
( (PetDog)obj2).dogName();
Why is it that the upstream is automatic, but downcasting has to be manual? Well, you see, a promotion may never fail. But if you have a group of different dogs, and you want to be dumped all of them, they had the possibility that some of these Dogs are of different types, i.e. PetDog , PoliceDog , and the process fails by throwing a ClassCastException .
It is for this reason that you need to delete your objects manually if you pointed your objects to the type of superclass.
Note. Here, referring to the fact that you do not change the memory address of your projects, when you omit it, it still remains the same, you simply group them by a certain type in this case Dog