In Java, a variable of the parent class can refer to an instance of the parent class, or it can refer to an instance of the child class.
Readers should look at a piece of code first:
- Public class Demo {
- public static void main(String[] args){
- Animal obj = new Animal();
- Obj. Cry();
- obj = new Cat();
- Obj. Cry();
- obj = new Dog();
- Obj. Cry();
- }
- }
- Class Animal{
- //Animal sounds
- public void Cry(){
- System. Out. println("Do not know how to call");
- }
- }
- Class Cat extends Animal{
- //Cat's Cry
- public void Cry(){
- System. Out. println("Meow meow ~");
- }
- }
- Class Dog extends Animal{
- //Barking of dogs
- public void Cry(){
- System. Out. println("Bark ~");
- }
- }
Operation Result:
Don't know how to call
Meow Meow ~
Bark ~
The above code defines three classes, namely, Animal, Cat, and Dog,cat, and the Dog class are inherited from the Animal class. The type of the obj variable is Animal, which can point to an instance of the Animal class or to an instance of the Cat and the Dog class, which is correct. That is, a variable of the parent class can refer to an instance of the parent class, or it can refer to an instance of the child class. Note that the reverse is wrong, because all cats are animals, but not all animals are cats.
It can be seen that obj can be either a human or a cat or a dog, it has different manifestations, which is called polymorphism. Polymorphism means that a thing has a different manifestation or form.
Again such as "human", there are many different expression or realization, TA can be a driver, teacher, doctor, etc., you hate yourself when you will say "Next life again," then you become a driver, teachers, doctors can, we say "human" with polymorphism.
There are three prerequisites for polymorphic existence: To have inheritance, to have overrides, to refer to a subclass object as a parent class variable.
When calling a method using Polymorphic mode:
- First check whether the method is in the parent class, if not, compile the error, and if so, check whether the subclass overrides the method.
- If the child class overrides the method, the method of the subclass is called, otherwise the parent class method is called.
As can be seen from the above example, one of the benefits of polymorphism is that when subclasses are relatively long, there is no need to define multiple variables, you can define only one variable of a parent class type to refer to instances of different subclasses. Take another look at the following example:
- Public class Demo {
- public static void main(String[] args){
- //With polymorphism, the host can feed many animals
- Master ma = new master();
- Ma. Feed(new Animal(), new Food());
- Ma. Feed(new Cat(), new Fish());
- Ma. Feed(new Dog(), new Bone());
- }
- }
- Animal class and its subclasses
- Class Animal{
- public void eat(food f){
- System. Out. println("I am a small animal that is eating" + F. ) Getfood());
- }
- }
- Class Cat extends Animal{
- public void eat(food f){
- System. Out. println("I'm a kitten, I'm eating" + F. ) Getfood());
- }
- }
- Class Dog extends Animal{
- public void eat(food f){
- System. Out. println("I'm a dog, I'm eating" + F. ) Getfood());
- }
- }
- Food and its sub-categories
- Class Food {
- public String getfood(){
- return "things";
- }
- }
- Class Fish extends food{
- public String getfood(){
- return "fish";
- }
- }
- Class Bone extends food{
- public String getfood www.zenmebanw.com (){
- return "Bone";
- }
- }
- Master Class
- Class Master{
- public void feed(Animal A, food f){
- An. Eat(f);
- }
- }
Operation Result:
I am a small animal, eating things
I'm a little kitty, I'm eating fish.
I'm a dog, eating bones.
The Master class's Feed method has two parameters, namely the Animal type and the food type, because it is the parent class, so you can pass an instance of the subclass to it so that the master class does not need multiple methods to feed the different animals.
Dynamic binding
To understand the nature of polymorphism, let's talk about the detailed flow of Java invocation methods.
1) The compiler looks at the declaration type and method name of the object.
Assume that you call Obj.func (param), and obj is an object of the Cat class. It is important to note that there may be multiple methods with the name Func but not the same parameter signature. For example, there may be method func (int) and func (String). The compiler will enumerate through all the methods named Func in all Cat classes and its parent class Animal, which has a public access property called Func.
In this way, the compiler obtains a list of all the candidate methods that might be called.
2) Next, the codec will check the parameter signature provided when calling the method.
Select this method if there is a method in all methods named Func that exactly matches the supplied parameter signature. This process is called overload resolution (overloading resolution). For example, if you call func ("Hello"), the compiler chooses the func (String) instead of the func (int). Because of the existence of an automatic type conversion, such as an int that can be converted to a double, if no method is found that is the same as calling the method parameter signature, the type conversion is performed and then the lookup continues, if there is no matching type at all, or if more than one method matches it, then the compilation error.
In this way, the compiler obtains the method name and parameter signatures that need to be called.
3) If the modifier of a method is private, static, final (static and final will be explained later), or is a constructor method, then the compiler will be able to know exactly which method should be called, and we call this called static binding binding).
By contrast, the method that is called relies on the actual type of the object and implements dynamic binding at run time. For example, if func ("Hello") is called, the codec will generate an instruction called Func (String) in a dynamically bound manner.
4) When the program is running and the method is invoked with dynamic binding, the JVM must invoke the method of the class that is most appropriate for the actual type of the object referenced by obj. We have assumed that the actual type of obj is cat, which is a subclass of Animal, which is called if Func (String) is defined in cat, otherwise it will be found in the Animal class and its parent class.
Each time the method is called for a search, the overhead is considerable, so the JVM has previously created a method lable for each class that lists the names of all the methods, the parameter signatures, and the classes to which they belong. This way, when the method is actually called, the virtual machine looks for the table only. In the example above, the JVM searches the Cat class's method table to find a method that matches the call to func ("Hello"). This method may be either Cat.func (string) or Animal.func (string). Note that if you call Super.func ("Hello"), the compiler will search the method table of the parent class for a row.
Assuming that the Animal class contains the three methods of Cry (), GetName (), Getage (), then its method table is as follows:
Cry (), Animal.cry ()
GetName (), Animal.getname ()
Getage (), Animal.getage ()
In fact, Animal also has the default parent class object (which will be explained later), which inherits the method of object, so the methods listed above are not complete.
Assuming the Cat class overrides the Cry () method in the Animal class, and a new method Climbtree () is added, its argument list is:
Cry (), Cat.cry ()
GetName (), Animal.getname ()
Getage (), Animal.getage ()
Climbtree (), Cat.climbtree ()
At run time, the process of calling the Obj.cry () method is as follows:
- The JVM first accesses the method table of the actual type of obj, possibly a method table for the Animal class, or a method table for the Cat class and its subclasses.
- The JVM searches the method table for a method that matches the cry () and, when found, knows which class it belongs to.
- The JVM calls the method.
Four. Java inheritance and polymorphism 4. Polymorphic and dynamic binding