"Polymorphism (Polymorphism)" comes from Greek, meaning "multiple forms". Most Java programmers regard polymorphisms as an object of the object, making it calling the correct method version. Despite this, this-oriented point of view leads to a polymorphic magical function, better than thinking of pure concepts. Polymorphism in Java is always a polymorph of subtypes. Almost mechanically produce some polymorphic behavior, so that we don't consider the types of problems involved. This paper studies a type of object-oriented object-oriented, analyzes how to distinguish the behavior of the object and the behavior of the object to be expanded. The polymorphisms that thrown Java are from inheritance, we can still feel that the interface in Java is a group of object sharing without public code. The polymorphic classification polymorphism is a very common concept in object-oriented language. Although we often mix polymorphisms, there are actually four different types of polymorphism. Before you start formal sub-type polymorphism, let's first look at the polymorphism in normal object-oriented. LUCA Cardelli and Peter Wegner ("On Understanding Types, Data Abstract, And Polymorphism" author, article reference resource link) divide multiple categories: specific and universal ---- Four small classes : Forced, overloaded, parameters and included. Their structure is as follows: In such a system, the polymorphism exhibits a variety of forms of ability. Universal polymorphisms have a large number of objects of the same structure, they have a common feature. Specific polymorphisms involve objects with small parts without the same feature. Four polymorphisms can be described below: Mandatory: an implicit method of type conversion. Overloaded: Use a marker as a plurality of meaning. Parameter: The same operation is provided for different types of parameters. Contains: The class contains an abstract operation. I will briefly introduce these polymorphisms before telling the child type. Forced Polymorphical Mandatory Polymorphism Implicit The parameters are converted into a compiler to avoid errors. In the following expressions, the compiler must determine the work you should do in the binary operator ' ': 2.0 2.0 2.0 2 2.0 "2" The first expression adds two DOUBLE's operands; This usage is specially declared in Java. The second expression adds Double type and int. This operation is not clear in Java. However, the compiler implicitly converts the second operand to a Double type and is a Double type addition. It is very convenient for programmers, otherwise a compilation error will be thrown, or forced programmers explicitly convert int to Double. The third expression adds Double to a String. Such actions are not defined in Java. So, the compiler converts Double to the String type and make them in series. Mandatory polymorphism will also occur in method calls. Suppose class derived inherits class base, class c has a method, prototype M (BASE), in the following code, the compiler implicitly converts the DeriveD class object DeriveD to the Base class. This implicit conversion makes the M (Base) method all parameters that can be converted to the Base class. C c = new c (); derived derived = new derived (); c.m (derived); and implicitly forced conversion, avoid the trouble of type conversion, reducing compilation errors. Of course, the compiler will still prioritize the type of object that matches the defined. The overloaded polymorphism is allowed to use the same operator or method to indicate a very different meaning. There are two meanings on the above program: two Double types are added; two strings are connected.
There is also an integer, long integer, and so on. The overload of these operators depends on the selection made according to the context. The previous compiler will implicit the operand to the type of fully compliant operator. Although Java explicitly supports overload, user-defined operator overload is not supported. Java supports user-defined functions overload. A class can have the same name, these methods can have different significance. In these overloaded methods, the number of parameters must be satisfied, and the parameter type in the same position is different. These differences can help the compiler distinguish between different versions. The compiler represents a different method in this unique characteristic, which is more effective than the name. According to this, all polymorphisms can be compiled. Compulsory and overloaded polymorphisms are classified as specific polymorphism because these polymorphisms are in a specific sense. These areas of being drawn to the programmer have brought great convenience. Forced polymorphism eliminates the type of trouble and compile errors. Heavy duty polymester like a piece of sugar, allowing programmers to express different methods with the same name, very convenient. The polymorphism of the parameters allows many types of abstraction into a single representation. For example, in the List abstraction, a set of objects having the same features are described, providing a universal template. You can reuse this abstract class by specifying a type. These parameters can be any type of user-defined, and a large number of users can use this abstraction class, so the parameter polymorphism is undoubted to become the most powerful polymorphism. At first glance, the abstraction of the above seems to be the function of java.util.list. However, Java actually does not support the real security type of style parameters, which is also the reason why Java.util.List and Java.util's other collection classes are written with the original java.LANG.Object (refer to my article) "A primordial interface?" To get more details). Java's single inheritance mode solves some problems, but does not exert all the features of parameter polymorphism. Eric Allen has a wonderful article "Behold The Power Of Parametric Polymorphism" describes the need for Java common type and it is recommended to give Sun's Java Specifications. Link) The included polymorphism contains the type of polymorphism passing the value and the collection of the set contains a polymorphic behavior. In many object-oriented languages including Java, the relationship is a subtype. Therefore, Java contains polymorphisms are a plurality of subtypes. In the early days, the polymorphisms mentioned by Java developers have the polymorphism of the species of the species. Through a type of view, we can see the powerful function of subtype polymorphism. In the following articles, we will carefully explore this issue. For the sake of concise, the polymorphisms in the following refers to the polymorphism. The UML class diagram of Figure 1 shows the simple inheritance relationship between classes and types to facilitate explanation of polymorphism. The model contains five types, 4 classes, and one interface. Although the UML is called a class diagram, I see it as a type. As described in "Thanks Type and Gentle Class," each class and interface are a type of user-defined. According to an independent implementation (such as a type of view), each rectangle in the figure below represents a type. From the implementation method, four types use the structure of the class, an interface to the interface. Figure 1: The code below the UML class chart below implements each user-defined data type, and I am very simple to implement.
/ * Base.java * / public class base {public string m1 () {return "base.m1 ()";} public string m2 {return "Base.m2 (" S ")"; } / * Itype.java * / interface itype {string m2; string m3 ();} / * derived.java * / public class derivedextends baseimplements itype {public string m1 () {return "derived.m1 () "} Public string m3 () {return" derived.m3 () ";}} / * derived2.java * / public class derived2extends derived {transfer s) {return s) {return" derived2.m2 (" s ")";} Public string m4 () {return "derived2.m4 ()";}} / * Separate.java * / public class SeparateImplements itype {public string m1 () {return "separate.m1 ()";} Public String M2 (String S) {return "Separate.m2 (" S ")";} public string m3 () {return "Separate.m3 ()";}} Use this type declaration and class definition, Figure 2 describes Java instructions from the viewpoint of the concept. Derived2 derived2 = new derived2 (); Figure 2: Derived2 objects Declare Derived2 objects, which is Derived2 class. The topmost of Figure 2 describes DeriveD2 to a collection window, although the DeriveD2 object under this is visible. Here is a hole for each DeriveD2 type. Each operation of the DeriveD2 object is mapped to the appropriate code, as described above. For example, the DeriveD2 object maps the M1 () method defined in Derived. Moreover, the M1 () method of the Base class is also overloaded. A delived2 reference variable does not have the right to access the M1 () method in the Base class. But this does not mean that it is not possible to use the method of super.m1 () to use this method. This code is not suitable for the variables of the derived2 reference. Derived2's other operational mappings also indicate the code execution of each type of operation. Since you have a DeriveD2 object, you can use any derived2 type variable to reference it. As shown in Figure 1, Derived, Base and ITYPE are the base class of Derived2. Therefore, it is useful to reference the Base class. Figure 3 depicts the conceptual point of view of the following statements. Base Base = derived2; Figure 3: Base class References Although the Base class is referenced to M3 () and M4 (), it does not change any feature and operation mapping of its DeriveD2 object. Whether it is the variable Derived2 or BASE, it is the same as the code executed by M1 () or M2 (String).
String tmp; // derived2 reference (figure 2) TMP = derived2.m1 (); // TMP is "derived.m1 ()" TMP = Derived2.m2 ("Hello"); // TMP is "derived2.m2 ( Hello) "// base reference (Figure 3) TMP = base.m1 (); // TMP IS" derived.m1 () "TMP = Base.m2 (" Hello "); // TMP IS" Derived2.m2 ( Hello "Two references call the same behavior because DeriveD2 objects do not know which method is called. Object only knows when to call, it will execute in the order inherited. Such order determines the m1 () method in the DeriveD2 object, and call the M2 (String) method in Derived2. This result depends on the type of object itself, not the type of reference. Despite this, it doesn't mean that you use Derived2 and Base references to be exactly the same. As shown in Figure 3, Base's reference can only see the operation of the base type. So, although Derived2 has mappings for methods M3 () and M4 (), the variable base cannot access these methods.
String tmp; // derived2 reference (figure 2) TMP = derived2.m3 (); // TMP IS "derived.m3 ()" TMP = derived2.m4 (); // TMP IS "derived2.m4 ()" / / Base reason (Figure 3) TMP = base.m3 (); // compile-time errortmp = base.m4 (); // compile-time error
The DeriveD2 object of the runtime maintains the ability to accept the M3 () and M4 () methods. Type restrictions make the base reference cannot call these methods during the compile period. The type of compile period checks like a set of armor, ensuring that the runtime object can only interact with the correct operation. In other words, the type defines the boundaries between the inter-object interactions. The consistency of a polymorphic dependency type is a polymorphic core. Each of the objects, static type inspector must confirm that such an attachment and its objects are consistent. When a reference is successfully attached to another different object, interesting polymorphism is generated. (Strictly speaking, the object type refers to the definition of class.) You can also attach several different references to the same object. Before starting more interesting scenes, let's take a look at why the following situation will not produce a polymorphism. A plurality of references are attached to an object to FIGS. 2 and 3 describe the examples of two and more than two or more references to an object. Although the Derived2 object retains the type of variable after being associated, the reference to the base type in Figure 3 is attached, and its function is reduced. The conclusion is obvious: the reference to a base class is attached to the object of derived class will reduce its capabilities. How can a development that chooses to reduce the subject's ability? This option is indirect. Suppose there is an object that is called REF is attached to a class containing the following method:
Public String Poly1 (Base Base) {Return Base.m1 ();
Calling Poly (BASE) with a DeriveD2 is the parameter type check:
Ref.Poly1 (Derived2);
Method Calling A local base type variable is attached to an introduced object. So, although this method only accepts the parameters of the base type, the derived2 object is still allowed. Development This does not have to choose a function of the loss. From the human eye, the attachment of the Base type reference leads to the loss of functionality. However, from the viewpoint of execution, each incoming Poly1 (BASE) is considered to be the object of Base. The execution machine does not care about there is a reference to the same object, which only focuses on the reference to the reference to another object. The type of these objects is inconsistent is not the main problem. The actuator only cares about the object to find the appropriate implementation. Type-oriented views show a huge power of polymorphism. Take us with a reference to multiple objects to see the polymorphic behavior that happens in Poly1 (Base). The following code creates three objects and passed by reference: derived2 derived2 = new derived2 (); derived derived = new derived (); base base = new base (); string tmp; TMP = REF. Poly1 (Derived2); // TMP IS "Derived.m1 ()" TMP = Ref.Poly1 (Derived); // TMP IS "Derived.m1 ()" TMP = Ref.Poly1 (Base); // TMP IS " Base.m1 () "
The implementation code of POLY1 (BASE) is a M1 () method that calls the passing parameters. Figures 3 and 4 illustrate the system-oriented architecture for the three classes to transmit three classes. Figure 4: Point the base reference to the DeriveD class, and the Base object, please note the mapping of the method M1 () in each figure. In Figure 3, m1 () calls the code of the Derived class; the comments in the above code indicate that PLOY1 (BASE) calls DeriveD.m1 (). Figure 4 The DeriveD object call is still the M1 () method of the DeriveD class. Finally, in Figure 4, the M1 () of the Base object call is the code defined in the base class. What is the charm of polymorphism? Let's take a look at the Poly1 (Base) code that accepts any parameters belonging to the base class. However, when he received a DeriveD2 object, it actually called the method of DeriveD version. When you derive other classes based on the base class, such as Derived, Derived2, Poly1 (BASE) can accept these parameters, and make the option to call the appropriate method. Polymorphism allows you to extend its use after completing POLY1 (BASE). This seems to be very magical. Basic understanding shows the principle of the polymorphic internal work. In the type of view, the code implemented by the underlying object is non-substantial. Importantly, the Type Checker Selects the appropriate code for each reference during compilation. Polymorphisms make developers to use the type of view, regardless of the details of the implementation. This helps separate the type and implementation (the actual use is separated by the interface and implementation). Object interface polymorphism depends on the separation of type and implementation, mostly to separate interfaces and implementation. But the following points seem to be very confused with the keywords of Java. More important make developers understand phrase "the interface to an object", typically, according to context, this phrase means that the method defined in all object classes, to all objects disclosed. This tendency to achieve a central point of view, making us more focusing on the ability of the object in operation. In Figure 3, the object surface of the reference panel is marked as "derived2 object". This panel lists all available methods for DeriveD2 objects. But to understand the polymorphism, we must liberate this level, and pay attention to the panel labeled "Base Reference" in a type of perspective. In this point, the type of reference variable indicates the surface of an object. This is just a surface, not an interface. Under the principle of the same type, we can use the object-oriented viewpoint to attach multiple references to an object. The understanding of the phrase of Interface to an Object is not determined. In the type concept, The interface to an Object Refers references the maximum possible view of the type of view ---- as shown in Figure 2. Point a reference to the same object to narrow the same object - as shown in Figure 3. The type concept can make people achieve the interaction between the objects to achieve detail. The type-oriented viewpoint is more encouraged to use an object to be referenced more than an object's interface. The reference type specifies the interaction between objects. When you think about an object, just understand his type, don't need to consider his implementation details. The polymorphic behavior described above is used by the polymorphism of the inheritance relationship with the inheritance relationship of the Java interface. The Java interface also supports user-defined types, relatively, Java interface mechanisms launched a polymorphic behavior on the type hierarchy. Assume a reference variable called REF and pointing it to a class object that contains a method: public string poly2 (iey itype) {return itype.m3 ();}
In order to understand the polymorphism in Poly2 (iTYPE), the following code creates two objects from different classes, and transmitting them to Poly2 (ITYPE): Derived2 derived2 = new derived2 (); Separate Separate = new Separate () String Tmp; TMP = Ref.Poly2 (Derived2); // TMP IS "Derived.m3 ()" TMP = Ref.Poly2 (Separate); // TMP IS "Separate.m3 ()"