In depth understanding of polymorphism in the three features of Java

Three features of Java

Object oriented programming has three characteristics: encapsulation, inheritance and polymorphism.

Encapsulation hides the internal implementation mechanism of the class, which can change the internal structure of the class without affecting the use, and also protect the data. To the outside world, its internal details are hidden, and only its access methods are exposed to the outside world.

Inheritance is to reuse the parent code. If there is an is-a relationship between two classes, inheritance can be used., At the same time, inheritance also paves the way for the realization of polymorphism. So what is polymorphism? What is the implementation mechanism of polymorphism? Please see me uncover for you one by one:

The so-called polymorphism refers to the specific type pointed to by the reference variable defined in the program and the method call issued through the reference variable. It is not determined during programming, but only during the running of the program, that is, a reference variable will point to the instance object of which class, and the method call issued by the reference variable is the method implemented in which class, It can only be determined during the running of the program. Because the specific class is determined only when the program is running, the reference variable can be bound to various class implementations without modifying the source program code, resulting in the change of the specific method called by the reference, that is, the specific code bound when the program is running can be changed without modifying the program code, so that the program can select multiple running states, This is polymorphism.

For example, you are a god of wine and have a special preference for wine. One day, I found that there were several cups in the table that contained baijiu. From outside, we could not know what wine was. Only after drinking it could we guess what kind of wine it was. Once you drink, this is Jiannanchun, drink again, this is Wuliangye, drink again, this is Jiugui wine Here we can describe it as follows:

Wine a = Jiannanchun

Liquor B = Wuliangye

Wine C = alcoholic liquor

What is shown here is polymorphism. Jiannanchun, Wuliangye and Jiugui wine are all subclasses of wine. We can reference different subclasses only through the parent class of wine. This is polymorphism - we will know the specific instance object pointed to by the reference variable only when running.

Indeed, to understand polymorphism, we must understand what is "upward transformation". In the inheritance, we briefly introduced the upward transformation. Here, in shuangduan Jianxia Xianmu dyeing review (win) is the parent class, and Jiannanchun (JNC), Wuliangye (wly) and Jiugui wine (JGJ) are the subclasses. We define the following codes:

JNC a = new JNC();

This code is very easy to understand. It just instantiates an object of Jiannanchun! But what about this?

Wine a = new JNC();

In this way, we define a wine type A, which points to the JNC object instance. Because JNC inherits from wine, JNC can automatically transform upward to wine, so a can point to JNC instance objects. This has a great advantage. In inheritance, we know that a subclass is an extension of the parent class, which can provide more powerful functions than the parent class. If we define a parent reference type pointing to a subclass, it can not only reference the commonness of the parent class, but also use the powerful functions of the child class.

However, there are some shortcomings in the upward transformation, that is, it will inevitably lead to the loss of some methods and attributes, so that we can not obtain them. Therefore, the reference of the parent class type can call all the properties and methods defined in the parent class. It can't catch up with the methods and properties that only exist in the child class -- - 1.

From the running results of the program, we find that A. fun1 () first runs fun1 () in the parent class wine Then run fun2 () in the subclass JNC.

Analysis: in this program, the subclass JNC overloads the method fun1() of the parent wine, overrides fun2(), and the overloaded fun1 (string a) and fun1() are not the same method. Because there is no such method in the parent class, the method will be lost after upward transformation, so the wine type reference of JNC cannot reference the fun1 (string a) method. If the subclass JNC overrides fun2 (), the wine reference to JNC will call the fun2 () method in JNC.

Therefore, we can summarize polymorphism as follows:

Due to the upward transformation, the parent class reference pointing to the child class can only access the methods and properties owned by the parent class. For the methods existing in the child class but not in the parent class, the reference cannot be used, although the method is overloaded. If the subclass overrides some methods in the parent class, these methods defined in the subclass must be used when calling these methods (dynamic connection and dynamic call).

For object-oriented, polymorphism is divided into compile time polymorphism and run-time polymorphism. Polymorphism during editing is static, which mainly refers to method overloading. It distinguishes different functions according to different parameter lists. After editing, it will become two different functions, so it can't be polymorphic at run time. The runtime polymorphism is dynamic, which is realized by dynamic binding, that is, what we call polymorphism.

Implementation of polymorphism

2.1 realization conditions

At the beginning, we mentioned inheritance, which is preparing for the implementation of polymorphism. The subclass child inherits the parent class father. We can write a parent type reference to the subclass. This reference can handle both the parent class father object and the child class child object. When the same message is sent to the subclass or parent object, the object will perform different behaviors according to its own reference, which is polymorphism. That is, polymorphism is that the same message makes different classes respond differently.

There are three necessary conditions for Java polymorphism: inheritance, rewriting and upward transformation.

Inheritance: there must be subclasses and parent classes with inheritance relationship in polymorphism.

Override: a subclass redefines some methods in the parent class. When these methods are called, the subclass's methods will be called.

Upward Transformation: in polymorphism, you need to assign the reference of the subclass to the parent object. Only in this way can the reference have the skills to call the methods of the parent class and the subclass.

Only when the above three conditions are met can we use unified logic implementation code to deal with different objects in the same inheritance structure, so as to execute different behaviors.

For Java, its polymorphic implementation mechanism follows a principle: when a superclass object references a subclass object with a reference variable, the type of the referenced object rather than the type of the reference variable determines whose member method to call, but the called method must be defined in the superclass, that is, the method covered by the subclass.

2.2 implementation form

There are two forms of polymorphism in Java. Inheritance and interfaces.

2.2. 1. Polymorphism based on inheritance implementation

The implementation mechanism based on inheritance is mainly reflected in the rewriting of some methods by the parent class and one or more subclasses inheriting the parent class. The rewriting of the same method by multiple subclasses can show different behaviors.

In the above code, JNC and JGJ inherit wine and override the drink() and tostring() methods. The result of program operation is to call the methods in the subclass and output the names of JNC and JGJ, which is the expression of polymorphism. Different objects can perform the same behavior, but they all need to perform it through their own implementation methods, which will benefit from the upward transformation.

We all know that all classes inherit from the superclass object, and the toString () method is also a method in object. When we write this:

The output is wine: JGJ.

The inheritance chain relationship among object, wine and JGJ is: JGJ ― > wine ― > object. So we can say this: when the method of the subclass overriding the parent class is called, only the method at the end of the object inheritance chain will be called.

But note that if you write this:

The output should be null because JGJ does not exist in the object inheritance chain.

Therefore, the polymorphism based on inheritance implementation can be summarized as follows: for the parent type that references a subclass, when processing the reference, it is applicable to all subclasses that inherit the parent class. Different subclass objects have different implementation of methods and different behaviors generated by executing the same action.

If the parent class is an abstract class, the child class must implement all the abstract methods in the parent class. In this way, all the child classes of the parent class must have a unified external interface, but their internal specific implementations can be different. In this way, we can use the unified interface provided by the top-level class to deal with the methods of this level.

2.2. 2. Polymorphism based on interface implementation

Inheritance is embodied by overriding several different subclasses of the same method of the parent class, which can be embodied by implementing the interface and covering several different classes of the same method in the interface.

In interface polymorphism, the reference to the interface must be an instance program that specifies a class that implements the interface. At run time, the corresponding method is executed according to the actual type of object reference.

Inheritance is single inheritance, which can only provide consistent service interfaces for a group of related classes. However, the interface can be multi inheritance and multi implementation. It can use a group of related or unrelated interfaces for combination and expansion, and can provide a consistent service interface. So it has more flexibility than inheritance.

3、 Classic examples.

Through the above description, we can say that we have a certain understanding of polymorphism. Now strike while the iron is hot. Let's take a look at an example. This example is a classic example of polymorphism, which is extracted from: http://blog.csdn.net/thinkGhoster/archive/2008/04/19/2307001.aspx 。

Operation results:

Here, results 1, 2 and 3 are understandable. I've been confused since 4. Why is the output not "B and B" for 4?

First, let's take a look at a sentence: when a superclass object references a subclass object with a reference variable, the type of the referenced object rather than the type of the reference variable determines whose member method to call, but the called method must be defined in the superclass, that is, the method overridden by the subclass. This sentence summarizes polymorphism. In fact, there is a priority for the invocation of object methods in the inheritance chain: this show(O) 、super. show(O) 、this. show((super)O) 、super. show((super)O) 。

analysis:

From the above procedure, we can see that a, B, C and d have the following relationship.

First, we analyze 5, A2 Show (c), A2 is a reference variable of type A, so this represents a, A2 Show (c) is found in class A, but not found, so it looks for (super) in the superclass of A. since a has no superclass (except object), it jumps to the third level, that is, this. Show ((super) o). The superclasses of C have B and a, so (super) O is B and a, and this is also a. show (a obj) is found in A. at the same time, A2 is a reference of class B and class B overrides show (a obj), Therefore, the show (a obj) method of subclass B will eventually be called, and the result is B and a.

In the same way, I can confirm other answers.

Methods have been found, but we still have some questions here. Let's look at this sentence: when a superclass object references a subclass object with a reference variable, the type of the referenced object rather than the type of the reference variable determines whose member method to call, but the called method must be defined in the superclass, that is, the method covered by the subclass. Here we use an example to illustrate the meaning of this sentence: A2 show(b) ;

Here A2 is a reference variable of type A, which refers to the B object. Therefore, according to the meaning of the above sentence, B determines whose method to call, so A2 Show (b) should call show (b obj) in B, and the result should be "B and B", but why is it different from the previous running result? Here, we ignore the following sentence "but the method called here must be defined in the superclass". Does show (b obj) exist in class a? It doesn't exist! So this sentence doesn't apply here? So is this sentence wrong? No! In fact, this sentence also implies this sentence: it still has to be recognized according to the priority of the calling method in the inheritance chain. Therefore, it will find show (a obj) in class A. at the same time, because B rewrites the method, it will call the method in class B. otherwise, it will call the method in class A.

Therefore, the principle followed by the polymorphic mechanism is summarized as follows: when a superclass object references a subclass object with a reference variable, the type of the referenced object rather than the type of the reference variable determines whose member method to call, but the called method must be defined in the superclass, that is, the method covered by the subclass, However, it still needs to confirm the method according to the priority of method calls in the inheritance chain, which is: this show(O) 、super. show(O) 、this. show((super)O) 、super. show((super)O) 。

summary

The above is the whole content of this article. I hope the content of this article can bring some help to your study or work. If you have any questions, you can leave a message.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>