In object-oriented programming language, polymorphism is the third basic characteristic after data abstraction and inheritance. Polymorphism separates what is done by separation and how it is done, separating the interface from the implementation from another angle. When we first touch polymorphism, we may be confused by the word itself, and if we call it "dynamic binding," many people can understand his deep meaning. In general, we call dynamic binding also called late binding, runtime binding.
(i) method call binding 1. Binding concept
Typically, we associate a method call with the same method body called a binding. If you bind before the program executes, we call this binding method a pre-binding. In a process-oriented language, such as C, this method is the default and unique. If we use early binding in Java, it is likely that the compiler will be confused by which method to bind in this vast inheritance implementation system. The solution is dynamic binding, a late-bound method that binds to the type of the object at run time.
In Java, dynamic binding is the default behavior. However, in a class, the normal method uses this method of dynamic binding, and there are cases where dynamic binding does not occur naturally.
2.final Retouching
If an attribute is final decorated, the implication is that it cannot be changed after initialization.
If a method is final decorated, the meaning is not overwritten. We often like to say this from a macro point of view, but why can't our real final-retouching approach be overwritten? Because the final modifier actually turns off dynamic binding. In Java, the final modification of the content can not be dynamically bound to the method, can not be dynamically bound without the concept of polymorphism, nature can not be overwritten.
3. "Overwrite" private method
In fact, we seldom set the method to private. If we "overwrite" the private method, we are only getting a new method. It's okay to be completely with the parent class. This should be noted that, perhaps, the interview will be asked: "Overwrite" in the subclass of the parent private method is allowed without error, but it is completely two no matter how.
4. Domain and Static methods
When we learn about polymorphism, we may think that everything can happen in a polymorphic manner. In fact, if we access a domain directly, this access will be parsed at compile time, we can refer to the following example:
Package polymorphic;/** * *@author quinnnorris * Domain does not have polymorphism */PublicClassPolymorphics {/** *@param args */PublicStaticvoidMain (string[] args) {TODO auto-generated Method stub Super sup =New Sub (); System.out.println ("Sup.field =" + Sup.field +", Sup.getfield () =" + Sup.getfield ()); Sub Sub =New Sub (); System.out.println ("Sub.field =" + Sub.field +", Sub.getfield () =" + Sub.getfield () +public int field = 0; Span class= "Hljs-keyword" >public int getfield () {return field; }}class Sub extends Super {public int field = 1; public int getField () {return field; } public int getSuperField () {return super.field;}}
Output Result:
Sup.field = 0, Sup.getfield () = 1
Sub.field = 1, Sub.getfield () = 1, Sub.getsuperfield () = 0
This example tells us that when we invoke a method, the body that chooses which method to execute is dynamically selected by the runtime. However, when we access the instance domain directly, the compiler accesses it directly according to the type represented by the object. There are static methods that are identical in this case. So we can make this conclusion:
- Normal method: Dynamic binding based on the type of the object entity
- Domain and Static methods: pre-binding based on the type of the object's representation
In layman's words, we look at what types are behind new, and how we look at the domain and static methods. = What type was declared earlier.
Although this seems to be a very easy to hang the question. But in practice, it's actually never (or rarely) going to happen. First, programmers who don't set the instance domain to private are basically all fired (the instance domain is rarely decorated as public). Second, we rarely set the name of the domain that we created in the subclass Sing Woo the parent class.
(ii) Constructors and polymorphic
In general, constructors are a very unique existence. This is also true when it comes to polymorphism. Although constructors are not polymorphic (they are actually decorated with static, although the static is implicitly declared), it is necessary to understand how the constructor works.
1. Constructor invocation Order
The constructor of the parent class is always called during the call of the subclass constructor, and is incrementally linked by the inheritance hierarchy so that the constructors of each parent class are called correctly. This is necessary because the constructor has a special task to check whether the object is properly constructed. A subclass method can only access its own members and cannot access members in the parent class. Only the constructor of the base class has the appropriate permissions to initialize its own elements. Therefore it is necessary to have each constructor be called, otherwise the correct complete object cannot be constructed.
Package Polymorphic;publicClassFather {/** *@param args */public static void main (string[] args) {TODO auto-generated Method StubNew F (); }}ClassA {a () {System.out.println ("A"); }}ClassBExtendsA {B () {System.out.println ("B"); }}class c extends b {C () {System.out.println ( "C");}} class d {D () {System.out.println ( Span class= "hljs-string" > "D"); }}class e {E () {System.out.println ( Span class= "hljs-string" > "E"); }}class f extends c {private d d = new D (); private e e = new E (); F () {System.out.println ( "F");}}
Output Result:
A
B
C
D
E
F
Seemingly accidental "ABCDEF" output results, in fact, we have carefully arranged.
This example is a very intuitive explanation of the constructor's calling rule, with the following three steps:
- Invokes the parent class constructor. This step is repeated recursively, until the most ancestor class, in turn, is lowered with the constructor.
- Initializes a constructor method that invokes a member in declaration order.
- Invokes the body of the subclass constructor.
Maybe I said this order, and everyone would think of super soon. Yes, that's right, super () can actually display the constructor method that you want to invoke in the calling parent class, but super () must be placed in the first row of the constructor, which is the rule. Our order is no problem, or in fact the first sentence in the constructor of F is super (). But we omit it by default.
(iii) Covariant return type characteristics
Java adds a covariant return type in SE5, which indicates that the overridden method in a subclass can return a seed class for the return type of the method of the parent class.
Package polymorphic;/** * *@author Quinnnorris * covariant return type */publicClassCovariant {/** *@param args */public static void main (string[] args) {TODO auto-generated Method stub A B =New B (); B.getc (). print (); A A =New A (); A.getc (). print (); }}class a{public C GetC () { return new C ();}} class B extends a{public D GetC () { return new D ();}} class c{public void print () {System.out.println ("C");}} class D extends c{public void print () {System.out.println ("D");}}
Output Result:
D
C
In the above example, Class D is inherited from Class C, and Class B is inherited from Class A, so in the Getc method covered by Class B, the return type can be converted to the type of a subclass (class D) of Class C.
(iv) Succession design
Often, inheritance is not our first choice, can use the combination of methods as much as possible, this means more flexible, if your code is-a and is-like-a too much, you should consider whether it should be replaced by has-a some. One common rule is to use inheritance to express differences between behaviors and to express state changes with fields.
And when it comes to inheritance, we often involve upward transformation and downward transformation. In Java, all transformations will be checked. Even if we were just doing a normal type of parentheses, we would still check it when we entered the runtime to make sure it was the type we wanted. If not, it returns a ClassCastException (class transformation exception). This behavior of checking the type during run is called run-time type recognition (RTTI).
Article turned from: http://blog.csdn.net/QuinnNorris/article/details/57413811
Java dynamic binding and polymorphism