Java Programming Ideas (VIII, polymorphic)

Source: Internet
Author: User
Tags export class

Tag: Name object dynamic binding expected Dir interface base class data required

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. Polymorphism can not only improve the organization and readability of code, but also create extensible programs.

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 relationship between types and coupling. Inheritance allows an object to be treated as its own type or its base type. This ability is extremely important because it allows multiple types (derived from the same base class) to be treated as the same type. And the same code can run on these different types with no difference. A polymorphic method call allows a type to exhibit differences from other similar types as long as they are all from the same base class. This distinction is expressed in terms of the behavior of the method, although these methods can be called by the same base class.

1, again on the upward transformation. The practice of taking a reference to an object as a reference to its base type is called upward transformation-because in the drawing of an inheritance tree, the base class is placed above. Why do we have to move up into a base class reference? It's mostly about reusing code. For example, we have a car class. Car there is one way to move. If we don't move up, we need to write a method of calling various car moves where the class begins. If we can move up, we can bind the method dynamically, so we don't have to write the method of calling the car, just write the moving method of calling car.

class extends car{
public void Move () {System.out.print ("H Move")};
Class K extends car{
public void Move () {System.out.print ("K Move")};
}
public class dirve{
If you use an upward transformation, this go method will not have to write, otherwise, in the event of adding a new car class, such as L, then you have to add a go (L) method here. It's not convenient.
public static void Go (H h) {
H.move ();
}
public static void Go (k k) {
K.move ();
}
public static void Main (string[] args) {
H h = new H ();
K k = new K ();
Go (h);
Go (k);
}
}

2, transfer.

1) method call binding. Associating a method call with the same method body is called a binding. Binding (implemented by the compiler and the linker, if any) before the program executes is called early binding. But if the arguments passed in at the beginning of the compilation are only references to the base class, the compiler does not know which method to invoke. So, the solution is late binding. Late binding means binding at run time based on the type of the object. Late binding is also known as dynamic binding or runtime binding. If a language wants to implement late binding, it must have a mechanism in place to judge 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 mechanisms vary from one programming language to another, but if you think about it, you have to place some kind of "type information" in the object anyway. In the previous example, you only need to change the Go method to go (car car).

In addition to the static method and the final method in Java (the private method belongs to the final method), all other methods are late-bound. After you declare a method as final, you can prevent others from overwriting the method. You can also effectively "turn off" dynamic binding.

2) produce the correct behavior. Once we know that all the methods in Java are polymorphic by dynamic binding, we can write code that deals only with the base class, and that code works correctly for all exported classes. Or in other words, send a message to an object and let the object decide what to do.

3) Extensibility. Because there are polymorphic mechanisms. We can add as many new types as we want to the system. You do not need to add or change the Go () method. Most or all of the methods follow the Go () model and only communicate with the base class interface. Such programs are extensible because new data types can be inherited from a common base class, adding functionality. The methods that manipulate the base class interface can be applied to the new class without any changes.

4) Defect: "Overwrite" private method.

 public  class   privateoverride{ private  void  f () {System.out.print (" Private f () " public  static  void   main (string[] args) {privateoverride po  = new   Derived (); 
  PO.F (); }} class Derived extends privateoverride{ public void f () {System.out.print ("Public f ()" /output:
Private F ()

The output we expect is public f (), but because the private method is automatically considered the final method, and the exported class is masked. So this is the case. The F () method in the derived class is a completely new method, and the F () method in the base class is not visible in the subclass derived and therefore cannot be overloaded. 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.

5) Defects: domain and static methods. Only the common method is polymorphic.

class super{
public int field = 0;
public int GetField () {return field;}
}
Class Sub extends super{
public int field = 1;
public int GetField () {return field;}
public int Getsuperfield () {return super.field;}
}
public class fieldaccess{
public static void Main (string[] args) {
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 () + ", sub.getsuperfield () =" + Sub.getsuperfield ());
}
}/*output:
Sup.field = 0, Sup.getfield () = 1

When a sub object is transformed into a super reference, any domain access operations are parsed by the compiler and therefore not polymorphic. This generally does not occur, because all domains are generally private and cannot be accessed directly. Accessible only through methods (for example, get methods).

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

3, constructors and polymorphism. First, the constructor is not polymorphic. (They are actually static methods, except that the static declaration is implicit).

1), the order in which the constructors are called. 1. Call the base class constructor. This step is repeated recursively, first of all to construct the root of this hierarchy, but the next layer of the export class, and so on, until the lowest layer of the export class. 2. Initialize methods that invoke members in the order they are declared. 3. Call the principal of the export class constructor.

2), inheritance and cleanup. When you create a new class by combining and inheriting, you never have to worry about the cleanup of the object. Child objects are usually left to the garbage collector for processing. If you do encounter problems, you must create a Dispose () method for the new class (the name can be self-determined). And because of inheritance, if we have other special cleanup actions that are part of garbage collection, you must overwrite the Dispose () method in the export class. When overriding the Dispose () method of the inherited class, it is important to remember to call the Dispose () method of the base class. Otherwise, the cleanup action for the base class does not occur.

3), the behavior of the Polymorphic method inside the constructor. Inside a generic method, a dynamically bound call is determined at run time because the object cannot know whether it belongs to the class that the method resides in, or the export class that belongs 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 may be quite unpredictable. Because the overridden method is called before the object is fully constructed. This can cause some hidden errors that are difficult to find. Conceptually, the work of the constructor is actually creating the object. Within any constructor, the entire object may only be partially formed-we only know that the base class object has been initialized. If the constructor is just a step in the process of building the object, and the class to which the object belongs is exported from the class to which the constructor belongs. Then the export portion is still not initialized at the moment the current constructor is being called. However, a dynamically bound method call is going out into the inheritance hierarchy, and it can invoke methods in the exported class. If we do this inside the constructor, it is possible to invoke a method, and the members manipulated by this method may not have been initialized.

class glyph{
void Draw () {System.out.print ("Glyph.draw ()");}
Glyph () {
System.out.print ("Glyph () before Draw ()");
Draw ();
System.out.print ("Glyph () after draw ()");
}
}

Class Roundglyph extends Glyph () {
private int radius = 1;
Roundglyph (int r) {
Radius = R;
System.out.print ("roundglyph.roundglyph (), radius =" +radius);
}
void Draw () {
System.out.print ("Roundglyph.draw (), radius =" +radius);
}
}

public class polyconstructors{
public static void Main (string[] args) {
New Roundglyph (5);
}
}/output:
Glyph () before draw
Roundglyph.draw (), radius = 0
Glyph () after draw ()
Roundglyph.roundglyph (), radius = 5

We expect the output to be 1, but the first output is actually 0. Here we have to introduce the initialization order in more detail.

1. Before anything else happens, initialize the storage space allocated to the object to binary 0.

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

3. Invoke the initialization method of the member in the order in which they are declared.

4. Call the constructor principal of the exported class.

4, covariant return type. A covariant return type is added to Java SE5, which indicates that the overridden method of the exported class can return some type of export of the return type of the base class method.

5, the design with inheritance. When you use out-of-the-box classes to create new classes, you should first consider the combination. The combination does not force our programming to enter the hierarchy of inheritance, and the composition is more flexible because it can dynamically select types. Instead, inheritance needs to know the exact type at compile time. Like I'm new to a car. I can make the program run from Mercedes to BMW or to Audi (this is also called State mode). But inherit, I once new, Mercedes Benz is Mercedes-Benz, and can no longer become a BMW. We cannot decide to inherit different objects during the run.

1), pure inheritance and extension. Pure inheritance: Only methods that have been established in the base class can be overridden in the export class. is the "is-a" relationship. Because the interface of a class has already determined what it should be. Inheritance ensures that all exported classes have the interface of the base class, and absolutely no less. This is a pure substitution. Because the exported class can completely override the base class, when used, there is absolutely no need to know any additional information about the subclass. Extension: Is the "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. While this is a useful approach, it depends on the specific situation. The disadvantage is that the extended portion of an interface in an exported class cannot be accessed by the base class. So once you're up, you can't call those new methods.

2), down transformation and runtime type identification. In Java, all transformations are checked. These are the behaviors that check the type during run time. In general, if you know the exact type of the object, you can try a downward transformation. If the type being transferred is correct, then the transformation succeeds. If it is wrong, it returns a ClassCastException exception.

Java Programming Ideas (VIII, polymorphic)

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.