Detailed Java Polymorphic object type conversion and dynamic binding _java

Source: Internet
Author: User
Tags access properties

Type conversions for Java polymorphic objects
The object type conversion referred to here refers to an object that has an inheritance relationship and is not an object of any type. When an object that does not have an inheritance relationship is coerced for type conversion, the Java runtime throws a Java.lang.ClassCastException exception.

In the inheritance chain, we call subclasses to the parent class "transition upward", and the parent class to the subclass is called "downward transition."

Often, we define variables as the type of the parent class, but refer to the subclass's object, which is a process of upward transformation. When the program runs, it implements the invocation of the subclass method through dynamic binding, that is, polymorphism.

However, sometimes in order to complete some of the functions that the parent does not have, we need to turn the transformed subclass object into subclasses and invoke the subclass method, which is the downward transformation.

Note: You cannot cast an object of a parent class directly into a subclass type, you can only convert a subclass object that has been transformed to a subclass type. In other words, the subclass object must be transformed upwards before it can be transformed downward. Take a look at the following code:

public class Demo {public
  static void Main (String args[]) {
    Superclass superobj = new superclass ();
    Sonclass sonobj = new Sonclass ();
    The following code throws an exception when it is run, and the parent class object cannot be directly converted to a subclass type
    //Sonclass sonObj2 = (sonclass) superobj;
    First upward transformation, then downward transformation
    superobj = sonobj;
    Sonclass sonObj1 = (sonclass) superobj;
  }
}
Class superclass{}
class Sonclass extends superclass{} 

The comment in line 7th is removed, and the runtime throws an exception, but the compilation can pass.

Because there is a risk of a downward transition, be sure to use the instanceof operator when you receive a reference to the parent class to determine whether the object is the subclass you want, and see the following code:

public class Demo {public
  static void Main (String args[]) {
    Superclass superobj = new superclass ();
    Sonclass sonobj = new Sonclass ();
    Superobj is not an instance of the Sonclass class
    if (superobj instanceof sonclass) {
      Sonclass sonObj1 = (sonclass) superobj;
    } else{
      System.out.println ("① cannot convert");
    }
    Superobj = sonobj;
    Superobj is an instance of the Sonclass class
    if (superobj instanceof sonclass) {
      Sonclass sonObj2 = (sonclass) superobj;
    } else{
      System.out.println ("② cannot convert");
}} Class superclass{}
class Sonclass extends superclass{}

Run Result:

① cannot be converted

Summary: The type conversion of an object is checked at run time, the upward transition occurs automatically, and the object being transformed must be a subclass of the current reference type.

Java polymorphism and dynamic binding
In Java, a variable of a parent class can refer to an instance of a parent class, or to an instance of a subclass.

Let the reader read 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 calls public
  void Cry () {
    System.out.println ("Don't know how to call");
  }
Class Cat extends animal{
  //cat calls public
  void Cry () {
    System.out.println ("Meow ~");
  }
Class Dog extends animal{
  //dog calls public
  void Cry () {
    System.out.println ("barking ~");
  }

Run Result:

Don't know how to call
Meow Meow ~
Bark ~

The above code, which defines three classes, is Animal, Cat, and Dog,cat and Dog classes are inherited from the Animal class. The obj variable is of type Animal, it can point to an instance of the Animal class, or it can point 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 to an instance of a subclass. Note that the converse is wrong, because all cats are animals, but not all animals are cats.

It can be seen that obj can be either human or cat or dog, it has different manifestations, which is called polymorphism. Polymorphism means that a thing has a different form or form of expression.

Another example is "human", there are a lot of different expression or realization, TA can be drivers, teachers, doctors, etc., you hate yourself will say "Next life", then you become a driver, teachers, doctors can, we say "human" with polymorphism.

There are three necessary conditions for polymorphic existence: inheritance, overriding, and parent-class variables referencing child-class objects.

When a method is invoked using polymorphic methods:
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 subclass overrides the method, the method of the subclass is invoked, otherwise the parent class method is invoked.

One of the benefits of polymorphism, as you can see from the above example, is that when subclasses are relatively long, there is no need to define multiple variables, and you can define only a variable of a parent class type to refer to instances of different subclasses. Please look at one of the following examples:

public class Demo {public
  static void Main (string[] args) {
    //with polymorphism, hosts 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, eating" + f.getfood ());
  }
}
Class Cat extends animal{public
  void Eat (Food f) {
    System.out.println ("I'm a kitten, eating" + f.getfood ());
  }
}
Class Dog extends animal{public
  void Eat (Food f) {
    System.out.println ("I'm a dog, eating" + f.getfood ());
  }
}
//Food and its subclass class
food{public
  String Getfood () {return
    "things";
  }
}
Class Fish extends food{public
  String Getfood () {return
    "fish";
  }
}
Class Bone extends food{public
  String Getfood () {return
    "bone";
  }
}
Master Class class
master{public
  void Feed (Animal, Food f) {
    an.eat (f);
  }
}

Run Result:

I am a small animal, eating things
I am a kitten, eating fish
I am a dog, eating bones

The feed method of the master class has two parameters, namely the Animal type and the Food type, because it is a parent class, so you can pass an instance of the subclass to it so that the master class does not require multiple methods to feed different animals.
Dynamic Binding

To understand the nature of polymorphism, here's a detailed flow of Java invocation methods.

1 The compiler looks at the declared type and method name of the object.

Suppose call Obj.func (param), obj is an object of the Cat class. It should be noted that there may be more than one method whose name is func but the parameter signature is different. For example, methods func (int) and func (String) may exist. The compiler will enumerate all the methods named Func in all Cat classes and the methods named Func in their parent class Animal that have access properties public.

The compiler then obtains a list of all the candidate methods that might be invoked.

2) Next, the codec checks the parameter signature provided when the method is invoked.

Select this method if there is a method that exactly matches the supplied parameter signature in all methods named Func. This process is referred to as overload resolution (overloading resolution). For example, if you call func ("Hello"), the compiler chooses Func (String) instead of func (int). Because of the existence of an automatic type conversion, such as int can be converted to double, if no method is found that is the same as calling the method parameter signature, the type conversion is done and then the lookup continues, if there is no matching type or if multiple methods match, compile error.

The compiler then obtains the method name and parameter signature that needs to be invoked.

3 If the modifier of the method is private, static, final (static and final will be explained later), or is a construction method, then the compiler will be able to know exactly which method should be called, which we call the static binding binding).

In this case, the invoked method relies on the actual type of the object and implements dynamic binding at run time. For example, call func ("Hello"), and the codec will dynamically bind to generate an instruction that calls Func (String).

4 when the program is run and the method is invoked with dynamic bindings, the JVM must invoke the method of the class that is most appropriate to the actual type of object referenced by obj. We have assumed that the actual type of obj is Cat, it is a subclass of Animal, and if Func (String) is defined in cat, it is called, otherwise it will be found in the Animal class and its parent class.

Each invocation of the method is searched for a considerable amount of time, so the JVM creates a method table for each of the classes (methods lable) that lists the names of all methods, the signature of the parameters, and the class to which they belong. This way, when the method is actually invoked, the virtual machine only looks for the table. In the example above, the JVM searches the method table of the Cat class to find a way to match the call to func ("Hello"). This method can be either Cat.func (string) or Animal.func (string). Note that if you call Super.func ("Hello"), the compiler will burst the search on the parent class's method table.

Assuming that the Animal class contains Cry (), GetName (), Getage () Three methods, 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 is explained later) that inherits the method of object, so the methods listed above are not complete.

Assuming that the Cat class overwrites The Cry () method in the Animal class and adds a new method Climbtree (), its argument list is:
Cry ()-> cat.cry ()
GetName ()-> animal.getname ()
Getage ()-> animal.getage ()
Climbtree ()-> cat.climbtree ()

At run time, the procedure for invoking the Obj.cry () method is as follows:
The JVM first accesses the method table of the actual type of obj, possibly the method table for the Animal class, or the method table for the Cat class and its subclasses.
The JVM searches the method table for a method that matches the cry () and finds out what class it belongs to.
The JVM invokes the method.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.