Java Programming Ideas Learn Note 8

Source: Internet
Author: User
Tags export class

Viii. polymorphic

In object-oriented programming language, polymorphism is the third basic feature after data abstraction and inheritance.

Polymorphism does what and how by separating, separating the interface from the implementation from another angle.

Encapsulation creates a new data type by merging features and behaviors. "Implementation Concealment" separates the interface and implementation by " privatizing " the details. The role of polymorphism is to eliminate the coupling relationship between types .

Inheritance allows an object to be treated as either its own type or its base class type. This ability is extremely important because it allows multiple types to be treated as the same type, and the same code can run on these different types without distinction. Polymorphic method calls allow one type to exhibit the difference from other similar types as long as they are derived from the same base class. This distinction is based on the different behavior of the method, although these methods can be called by the same base class.

1. Binding

① method Call binding associating a method call with the same method body is called a binding . Binding before the program executes (implemented by the compiler and the linker) is called early binding .

Binding based on the type of the object at run time, called late binding (polymorphic binding or run-time binding). If a language wants to implement late binding, it must have a mechanism to determine the type of the object at run time, thus invoking the appropriate method. That is, the compiler never knows the type of the object, but the method invocation mechanism can find the correct method body and call it. Late binding mechanism a type information must be placed in the object in any case.

In addition to the static method and the final method in Java (theprivate method belongs to the final method), all other methods are late-bound.

  ② produce the right behavior

All methods in Java are polymorphic by dynamic binding.

The base class establishes a common interface for all exported classes that inherit from it-that is, all exported classes can make all the behavior of the base class. Export to provide a separate behavior for each particular object by overriding the definition of these behaviors.

  ③ Scalability

A program that communicates only with the base class can be extensible because new data types can be inherited from common types, adding functionality. The methods that manipulate the base class interface can be applied to the new class without any changes.

Polymorphism is an important technique that allows programmers to "separate things from the unchanging."

  ④ defect: "Overwrite" private method

If we try to do this:

 Public classPrivateoverride {Private voidF () {System. out. println ("private F ()"); }     Public Static voidMain (string[] args) {privateoverride po=NewDerived ();    PO.F (); }}classDerived extends Privateoverride { Public voidF () {System. out. println ("Public f ()"); }}/*outputprivate F ()*/

The output we expect is public f (), but because the private method is automatically considered to be the final method (hence the pre-binding, judged by the reference type), and the exported class is masked. Therefore, in this case, the f () method in theDerived class is a completely new method, since the F () method in the base class is not visible in the subclass and cannot even be overloaded.

Conclusion: Only non-private methods can be overwritten. In an export class, it is best to use a different name for the private method in the base class.

  ⑤ defects: Domain and Static methods

Only normal method calls can be polymorphic. For example, if you access a domain directly, the access will be parsed by the compiler. Any domain access operation will be parsed by the compiler and therefore not polymorphic.

If a method is static, its behavior is not polymorphic. A static method is associated with a class, not a single object.

2. Constructors and polymorphic

Although constructors are not polymorphic (they are actually static methods), it is important to understand how constructors operate in complex hierarchies through polymorphism.

① Constructor Call order

The constructor of the base class is always called during the construction of the exported class, and is incrementally linked by the inheritance hierarchy so that the constructors of each base class can be called. This makes sense because the constructor has a special task: to check whether the object is properly constructed. An export class can only access its own members and cannot access members in the base class (the base class members are usually private types). Only the constructor of the base class has the appropriate knowledge and permissions to initialize its own elements. Therefore, all constructors must be called, otherwise it is not possible to construct the complete object correctly. This is why the compiler has to force each export class to call the constructor. In the constructor body of the exported class, if you do not explicitly specify that a base class constructor is called, it will silently invoke the default constructor. If there is no default constructor, the compiler will give an error (if a class does not have a constructor, the compiler will automatically synthesize a default constructor).

Look at the following example, which shows the composition, inheritance, and polymorphic build order:

classMeal {Meal () {System. out. println ("Meal ()"); }}classBread {Bread () {System. out. println ("Bread ()"); }}classCheese {Cheese () {System. out. println ("Cheese ()"); }}classLettuce {lettuce () {System. out. println ("lettuce ()"); }}classLunch extends Meal {Lunch () {System. out. println ("Lunch ()"); }}classProtablelunch extends Lunch {protablelunch () {System. out. println ("Protablelunch ()"); }} Public classSandwich extends Protablelunch {PrivateBread B =NewBread (); PrivateCheese C =NewCheese (); PrivateLettuce L =Newlettuce ();  PublicSandwich () {System. out. println ("Sandwich()"); }     Public Static voidMain (string[] args) {NewSandwich (); }}/*outputmeal () Lunch () Portablelunch () Bread () Cheese () lettuce () Sandwich ()*/

The above output shows that the call constructor follows the following order:

1) Call the base class constructor. This step is repeated recursively, first of all to construct the root of this hierarchy, then the next layer of the export class, and so on, until the lowest layer of the export class.

2) invokes the initialization method of the member in the Order of Declaration.

3) Call the principal of the exported class constructor.

Inside the constructor, we have to make sure that the members we want to use are already built.

  ② Inheritance and cleanup

If we have other special cleanup actions that are part of garbage collection, you must override the Dispose () method in the export class. When overriding the Dispose () method of the inherited class, it is important to remember to call the base class version of the Dispose () method, otherwise the base class cleanup action does not occur.

The order of destruction should be reversed in order of initialization.

  Behavior of polymorphic methods within the ③ constructor

The hierarchy of constructor calls poses an interesting dilemma-what happens if a dynamic binding method of the object being constructed is called inside a constructor?

Within a generic method, the invocation of a dynamic binding is determined at run time, because the object cannot know whether it belongs to the same class as the method or the export class belonging to that class.

If you want to invoke a dynamic binding method inside the constructor, you need to use the overridden definition of that method. However, the effect of this call can be unpredictable because the overridden method is called before the object is fully constructed, which can cause some hidden errors that are difficult to find.

The initialization sequence described above is not complete, and this is the key to solving this problem. the actual process of initialization is:

1) Initialize the storage space allocated to the object to binary 0 before anything else occurs.

2) Call the base class constructor as described earlier.

3) invokes the initialization method of the member in the order in which it is declared.

4) Call the constructor body of the exported class.

The advantage of this is that everything is initialized at least to "0".

There is a valid guideline for writing the constructor: "Use the simplest possible method to get the object into a normal state, and avoid invoking other methods if you can." "The only methods that can be safely called in the constructor are the final methods in the base class (also applicable to private methods).

3. Covariant return type  

A covariant return type is added in Java SE5, which indicates that an overridden method in an exported class can return some type of export of the return type of a base class method:

classGrain { PublicString toString () {return "Grain"; }}classWheat extends Grain { PublicString toString () {return "Wheat" }}classMill {Grain process () {return  NewWheat ();}}classWheatmill extends Mill {Wheat process () {return NewWheat ();}} Public classCovariantreturn { Public Static voidMain (string[] args) {Mill m=NewMill (); Grain g=m.process (); System. out. println (g); M=NewWheatmill (); G=m.process (); System. out. println (g); }}/*outputgrainwheat*/

4. Design with inheritance

  A better way is to first select "Combine". The combination is more flexible because it can dynamically select a type (hence the behavior is selected), whereas inheritance needs to know the exact type at compile time.

classActor { Public voidAct () {}}classHappyactor extends Actor { Public voidAct () {System. out. println ("Happyactor"); }}classSadactor extends Actor { Public voidAct () {System. out. println ("Sadactor"); }}classStage {PrivateActor actor =NewHappyactor ();  Public voidChange () {actor =Newsadactor ();}  Public voidPerformplay () {actor.act ();}} Public classtransmogrify { Public Static voidMain (string[] args) {Stage stage=NewStage ();        Stage.performplay ();        Stage.change ();    Stage.performplay (); }}/*Outputhappyactorsadactor*/

  The stage object contains a reference to the actor and can change the actual object at run time, and the behavior of the Performplay () changes accordingly. In this way, we gain dynamic flexibility during operation (this is also known as State mode ).

  ① Pure inheritance and extension

  Pure inheritance is a "is-a" relationship. The export class has the same interface as the base class, and the base class can receive any information sent to the exported class.

An extension is a "is-like-a" relationship because the exported class is like a base class-it has the same basic interface, but it also has additional features implemented by additional methods. The extended portion of an interface in an exported class cannot be accessed by a base class, so once we have transformed upward, we cannot invoke those new methods.

  ② down transformation and runtime type recognition

As the upward transformation loses the specific type information, we think that by going down the transformation should be able to get type information, in the Java language, all transformations will be checked. If the type does not match, a classcastexceptionis returned. This behavior of checking the type during run is called Runtime type recognition (RTTI).

5. Summary Polymorphism means "different forms". In object-oriented programming, we hold the same interface inherited from the base class, and use different forms of the interface: different versions of the dynamic binding method.

Java Programming Ideas Learn Note 8

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.