Implementation Mechanism of polymorphism in Java

Source: Internet
Author: User

Polymorphism is an important mechanism for object-oriented programming code reuse. We have mentioned Java polymorphism more than once. Java Runtime polymorphism: in the article on inheritance and interface implementation, we have introduced in detail the dynamic method scheduling of Java Runtime polymorphism. Today we go deep into the Java core again, learn the implementation of polymorphism in Java.

The word "polymorphism (polymorphism)" comes from Greek, meaning "multiple forms ". Most Java programmers regard polymorphism as a capability of objects so that they can call the correct method version. Even so, this implementation-oriented view leads to the magic of polymorphism, better than simply looking at polymorphism as a pure concept.

Polymorphism in Java is always subtype polymorphism. Almost mechanically produces some polymorphism, so that we do not consider the type issues involved. This article studies a type-Oriented Object viewpoint and analyzes how to separate the behavior that an object can express from the behavior that the object will show. Aside from the fact that polymorphism in Java comes from the concept of inheritance, we can still feel that interfaces in Java are a group of objects that do not have public code to share and implement.

Polymorphism Classification

Polymorphism is a common concept in object-oriented languages. Although we often confuse polymorphism, there are actually four different types of polymorphism. Before starting the formal discussion of subtype polymorphism, let's take a look at the polymorphism in common object-oriented systems.

Luca cardelli and Peter Wegner ("On understanding types, data processing action, and polymorphism) polymorphism is divided into two categories-specific and general---four sub-categories: forced, overloaded, parameter and included. Their structure is as follows:

In such a system, polymorphism shows various forms of ability. Generic polymorphism references a large number of objects of the same structure type and they share common features. Specific polymorphism involves a small part of objects without the same features. Four polymorphism types can be described as follows:

◆ Mandatory: A implicit type conversion method.

◆ Reload: Use a flag as multiple meanings.

◆ Parameter: provide the same operation for different types of parameters.

◆ Included: Abstract operations of class inclusion relationships.

I will briefly introduce these polymorphism before talking about subtype polymorphism.

Forced Polymorphism

Forced polymorphism implicitly converts a parameter to a type that the compiler deems correct in some way to avoid errors. In the following expressions, the compiler must determine what the binary operator '+' should do:

2.0 + 2.0

2.0 + 2

2.0 + "2"

The first expression adds the operands of two double values. This is specifically stated in Java.

The second expression adds the double and INT types. This operation is not clearly defined in Java. However, the compiler implicitly converts the second operand to the double type and adds the double type. It is very convenient for programmers. Otherwise, a compilation error will be thrown, or the programmer is forced to explicitly convert int to double.

The third expression adds double to a string. Such operations are not defined in Java. Therefore, the compiler converts the double type to the string type and concatenates them.

Forced polymorphism also occurs in method calls. Assume that the class derived inherits the class base. Class C has a method and its prototype is m (base). In the following code, the compiler implicitly converts the derived class object derived to the base class object. This implicit conversion enables the M (base) method to use all the parameters that can be converted to the base class.

 
 
  1. C c = new C();  
  2.  
  3. Derived derived = new Derived();  
  4.  
  5. c.m( derived );  

In addition, implicit forced conversion can avoid the trouble of type conversion and reduce compilation errors. Of course, the compiler will still give priority to verifying the object types that conform to the definition.

High-load Polymorphism

The overload allows identical operators or methods to represent completely different meanings. '+' Has two meanings in the above program: the sum of two double-type numbers; the two strings are connected. There are also integer addition, long integer type, and so on. The overloading of these operators depends on the compiler's selection based on the context. In the past, the compiler implicitly converted the operand to a type that fully complies with the operator. Although Java explicitly supports overloading, it does not support user-defined operator overloading.

JAVA supports User-Defined Function overloading. A class can have methods with the same name. These methods can have different meanings. In these overload methods, the number of parameters must be different, and the parameter types at the same location are different. These differences can help the compiler differentiate methods of different versions.

The compiler uses this unique feature to represent different methods, which is more effective than using a name. Therefore, all the polymorphism behaviors can be compiled.

Both forced and overloaded polymorphism are classified as specific polymorphism because these multi-States are in a specific sense. These transferred polymorphism features bring great convenience to programmers. Forced polymorphism eliminates troublesome types and compilation errors. Heavy-load polymorphism is like a piece of sugar. It is convenient for programmers to express different methods with the same name and word.

Parameter Polymorphism

Parameter polymorphism allows many types to be abstracted into a single representation. For example, a list abstract class describes a group of objects with the same features and provides a general template. You can specify a type to reuse this abstract class. These parameters can be of any user-defined type and can be used by a large number of users. Therefore, parameter polymorphism is undoubtedly the most powerful polymorphism.

At first glance, the abstract class above seems to be a function of Java. util. List. However, Java does not actually support true parameter polymorphism of the security type style, which is also Java. util. list and Java. other collection classes of util use the original Java. lang. object write reason (refer to my article "a primordial interface? "To get more details ). Java's single inheritance method solves some problems, but does not play all the functions of parameter polymorphism. Eric Allen has a wonderful article "behold the power of parametric polymorphism", which describes general Java type requirements and recommends Sun's Java specification requirements # document No. 000014 "add
Generic types to the Java programming language. "(refer to the Resource Link)

Inclusion Polymorphism

Polymorphism is implemented through the value type and the Set's inclusion relationship. In many object-oriented languages including Java, the inclusion relationship is subtype. Therefore, Java's inclusion polymorphism is sub-type polymorphism.

In the early days, the polymorphism mentioned by Java developers was specifically the subtype polymorphism. From a type-oriented perspective, we can see the powerful functions of subtype polymorphism. We will discuss this issue carefully in the following articles. For the sake of conciseness, polymorphism in the following sections refers to inclusion polymorphism.

Type-oriented view

The UML class diagram in Figure 1 provides a simple inheritance relationship between classes and types to facilitate the interpretation of the multi-State mechanism. The model contains five types, four classes, and one interface. Although UML is called a class diagram, I regard it as a Type diagram. As described in "Thanks type and gentle class," each class and interface is a user-defined type. Each rectangle in an independent implementation (such as type orientation) represents a type. From the implementation method, four types Use the class structure, and one uses the interface structure.

 
Figure 1: UML class diagram of the Demo code

The following code implements each user-defined data type, and I write the implementation very easily.

With such a type declaration and class definition, Figure 2 describes Java commands from the conceptual point of view.

Derived2 derived2 = new derived2 ();

 
Figure 2: references on the derived2 object

The object derived2 is defined in the preceding section. It belongs to the derived2 class. The top layer of Figure 2 describes derived2 reference as a set window, although the derived2 object under it is visible. Here, a hole is left for each operation of the derived2 type. Each operation of the derived2 object maps the appropriate code, as described in the above Code. For example, the derived2 object maps the M1 () method defined in derived. The M1 () method of the base class is also overloaded. The referenced variable of a derived2 does not have access to the overloaded M1 () method in the base class. However, this does not mean that this method cannot be called using the super. M1 () method. It is related to the referenced variable derived2.
The code is not suitable. Other operation Mappings of derived2 also indicate code execution for each type of operation.

Since you have a derived2 object, you can use any derived2 type variable to reference it. As shown in 1, derived, base, and itype are both base classes of derived2. Therefore, the reference of the base class is very useful. Figure 3 describes the concepts of the following statements.

Base base = derived2;

 

 
Figure 3: base class references attached to the derived2 object

Although the reference of the base class no longer needs to access m3 () and M4 (), it does not change any feature and operation ing of its derived2 object. Whether the variable derived2 or base, the Code executed by calling M1 () or M2 (string) is the same.

The two references call the same behavior because the derived2 object does not know which method to call. The object only knows when to call it. It is executed in the sequence of inheritance implementation. This order determines that the derived2 object calls the M1 () method in derived and calls the M2 (string) method in derived2. The result depends on the type of the object, rather than the type of the reference.

However, it does not mean that the effects of using derived2 and base references are exactly the same. As shown in 3, only operations of the Base type can be seen in the base reference. Therefore, although derived2 maps Methods m3 () and M4 (), the variable base cannot access these methods.

The derived2 objects in the runtime maintain the ability to accept the M3 () and M4 () methods. The Type restriction prevents base references from calling these methods during compilation. The type check in the compilation phase is like a set of armor, ensuring that the runtime objects can only interact with the correct operations. In other words, a type defines the boundaries between objects.

Polymorphism dependence

Type consistency is the core of polymorphism. For each reference on the object, the static type checker should confirm that such attachment is consistent with the object hierarchy. When a successful reference is attached to another different object, interesting polymorphism occurs. (Strictly speaking, object types refer to the definition of classes .) You can also attach several different references to the same object. Before starting a more interesting scenario, let's take a look at the reason why there is no polymorphism in the scenario.

Multiple references are attached to one object.

The example in figures 2 and 3 shows that two or more references are attached to an object. Although the derived2 object retains the variable type after being attached, the function of the base type reference attachment in Figure 3 is reduced. Conclusion: attaching the reference of a base class to the object of the derived class reduces its capability.

How can I choose a solution to reduce the object capability for development? This option is indirect. Assume that a reference named ref is attached to an object of the class containing the following method:

Calling poly (base) with a derived2 parameter meets the parameter type check:

Method call attaches a local base type variable to an introduced object. Therefore, although this method only accepts base-type parameters, the derived2 object is still allowed. Therefore, you do not have to select a solution for function loss. From the situation that the human eye sees when using the derived2 object, the attachment of the base type reference causes the function loss. However, from the execution point of view, each input poly1 (base) parameter is considered as a base object. The executor does not care that multiple references point to the same object. Instead, it only transmits the reference pointing to another object to the method. Inconsistent types of these objects are not the main issue. The executor only needs to find an appropriate implementation for the runtime object. Type-oriented view presentation
The capability of polymorphism.

References attached to multiple objects

Let's take a look at the multi‑state row that occurs in poly1 (base. The following code creates three objects and transmits them to poly1 (base) through reference ):

The implementation code of poly1 (base) is to call the M1 () method of the passed parameters. Figure 3 and figure 4 show the type-Oriented Architecture used when three class objects are passed to the method.

 
Figure 4: point the base reference to the derived class and Base Object

Note the M1 ing of M1 () in each graph. In Figure 3, M1 () calls the code of the derived class; the comment in the code above indicates that ploy1 (base) calls derived. M1 (). In Figure 4, the derived object still calls the M1 () method of the derived class. Finally, in figure 4, the M1 () called by the base object is the code defined in the base class.

What is the charm of polymorphism? Let's take a look at the poly1 (base) code. It can accept any parameter that belongs to the base class category. However, when it receives a derived2 object, it actually calls the derived version method. When you derive other classes from the base class, such as derived, derived2, and poly1 (base), you can accept these parameters and choose to call the appropriate method. Polymorphism allows you to expand its usage after completing poly1 (base.

This looks amazing. The basic understanding shows the internal working principle of polymorphism. In the type-oriented view, the Code implemented by the underlying object is non-substantive. It is important that the type checker selects the appropriate code for each reference during compilation to implement its method. Polymorphism allows developers to use the type-oriented viewpoint without considering the implementation details. This helps to split types and implementations (the actual use is to separate interfaces from implementations ).

Object Interface

Polymorphism depends on the separation of types and implementations, and is used to separate interfaces and implementations. However, the following points seem to confuse the Java keyword interface.

More importantly, let developers understand the phrase "the interface to an object". Typically, according to the context, this phrase refers to the methods defined in all object classes, to make all objects public. This kind of view tends to be implementation-centered. Compared with the type-oriented view, we pay more attention to the ability of objects during runtime. In Figure 3, the object surface of the reference panel is marked as "derived2 object ". This Panel lists all available methods for the derived2 object. But to understand polymorphism, we must be freed from the implementation level, and pay attention to the panel marked as "base reference" in the type-oriented perspective. In this sense, the type of the referenced variable specifies the surface of an object. This is just a surface, not an interface. With the consistency of types, we can use
To attach multiple references to an object. I have no definite understanding of the phrase "interface to an object.

In the concept of type, the interface to an object refers references the case where the maximum possibility of Type orientation is 2. Narrowing down the point of reference of a base class to the same object-3. The concept of Type allows people to get the essentials of separating objects from each other in detail. Compared with an object interface, the type-oriented view encourages people to use the reference of an object. The reference type specifies the interaction between objects. When you think about what an object can do, you only need to understand its type, instead of considering its implementation details.

Java Interface

The polymorphism mentioned above uses the child-type relationship established by the class inheritance relationship. Java interfaces Also support user-defined types. Correspondingly, the Java interface mechanism starts the multi-state behavior established on the type hierarchy. Assume that a reference variable named ref points to a class object that contains the following methods:

To understand the polymorphism in poly2 (itype), the following code creates two objects from different classes and passes them to poly2 (itype) respectively ):

The above code is similar to the discussion about polymorphism in poly1 (base. The implementation code of poly2 (itype) is to call the M3 () method of the local version of each object. As in the past, the comments of the Code indicate the cstring type results returned by each call. Figure 5 shows the conceptual structure of calling poly2 (itype) twice:

 
Figure 5: itype reference pointing to derived2 and separate objects

Methods The similarities of polymorphism behavior in poly1 (base) and poly2 (itype) can be seen from the perspective. We can see the skills of the two code segments by improving our understanding at the first layer and then improving the first layer. The base class references the class that is passed as a parameter and calls the object method according to the type restriction. The reference neither knows nor cares which piece of code is executed. The child-type relationship check during compilation ensures that the passed object has the ability to select the appropriate implementation code when called.

However, they have an important difference in the Implementation Layer. In the poly1 (base) Example (figure 3 and figure 4), the class inheritance structure of the Base-Derived-Derived2 provides conditions for the establishment of the Child-type relationship and determines which code the method calls. In the poly2 (itype) Example (5), a completely different dynamic occurs. Derived2 and separate do not share any implementation layers, but they demonstrate polymorphism through reference of itype.

This kind of polymorphism makes the Functional Significance of Java interfaces very obvious. The UML class diagram in Figure 1 illustrates that derived is a child type of base and itype. Java implements multi-type inheritance by completely separating the implementation details from the type definition method, and there is no annoying problem caused by multi-inheritance prohibited by Java. Classes that are completely out of the Implementation hierarchy can be grouped by Java interface implementation. In Figure 1, the interface itype, derived, separate, and other child types of this type should be grouped into one group.

According to this completely different implementation-level classification method, Java interface mechanism becomes more convenient for polymorphism, even if there is no shared implementation or rewrite method. As shown in figure 5, an itype reference accesses the M3 () method of the derived2 and separate objects using the polymorphism method.

Explore object interfaces again

Note the dering method of the derived2 and separate objects in Figure 5 to M1. As mentioned above, each object's interface contains method M1 (). However, there is no way to use these two objects to make method M1 () show polymorphism. It is not enough for each object to possess an M1 () method. There must be a type that can operate the M1 () method. Through this type, you can see the object. These objects seem to share the M1 () method, but polymorphism is impossible without a common base class. The concept of multistate is mixed through the interface of the object.

Conclusion

From the sub-type polymorphism established by the object-oriented polymorphism described in the full text, you can clearly understand this type-oriented viewpoint. If you want to understand the idea of subtype polymorphism, you should shift your attention from the implementation details to the type. Type divides objects into groups and manages interfaces of these objects. The inheritance hierarchy of types determines the type relationships required to implement polymorphism.

Interestingly, the implementation details do not affect the hierarchy of subtype polymorphism. The type determines the method called by the object, and the Implementation determines how the object executes this method. That is to say, the type indicates the responsibility, while the implementation is the specific implementation. After separating the implementation from the type, we seem to see the two parts dancing together. The class determines the name of the dance partner and the dance, and the implementation is the designer of the dance action.

Related Article

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.