Polymorphic, Java object-oriented programming features

  Polymorphism is one of the three major features of object-oriented programming and one of the ultimate manifestations of object-oriented thinking. Before understanding polymorphism, you need to master the concepts of inheritance, rewriting, and parent class references pointing to subclass objects. Students who have not fully understood inheritance can enter the portal: the three major characteristics of Java object-oriented programming-inheritance.
  
  1.
  
  In the inheritance of abstract classes , we have understood the relationship between the child and parent classes and how to design the child and parent classes. If multiple entity classes already exist, defining the parent class is actually a process of continuously extracting common coincident parts. Multiple inheritance relationships will be generated if necessary. In the process of extraction and sorting, in addition to the attributes can be reused, there are many methods can also be reused, assuming a graphic example: rectangle, circle, can have two methods of perimeter and area, but the calculation method is completely different, The relationship between the rectangle and the circle must not constitute a parent-child relationship, so you can only inherit a parent class at the same time, then the question arises, what do these two classes have in common?
  
  The technical pictures
  
  seem to have nothing in common except for the graphics. The rectangle has two sets of sides, and the circle is described by the radius, if it is necessary to connect together. . . Wait a moment (in the flash of aura, please do not disturb)! ! ! Is it possible to calculate the circumference and area? If you think about it carefully, you can tell the truth, but this is abstract!
  
  If this is really the case, there can only be a vague idea. Since the attributes describing the graphics cannot be shared, they should be placed in two subclasses. How to calculate the perimeter and area? If the corresponding method is defined in the parent class, how to write the parameter list? How to fill the method body? This pit seems to be a bit big. Next, we will fill this lavishly.
  
  1. Abstraction and Abstract Classes
  
  In the above example, we encountered a situation where there are two logically seemingly related classes, and we want to connect them, because doing so can improve efficiency, but in the process of implementation It is found that this common point is a bit too vague, and it is difficult to describe it with code. It is even more convenient to use it separately. At this time, it is necessary to introduce an abstract concept. The corresponding keyword is abstract.
  
  Abstract can modify methods. After modification, it is called abstract method.
  
  Abstract can modify the class. After modification, it is called abstract class.
  
  Abstract cannot be used together with static modifier.
  
  So what if abstract is used? This means that the specified methods and classes are difficult to express, then. . . No need to express it! For the parent class of the rectangle class (Rectangle) and the circle class (Circle): the figure class (Figure), we can only conclude that he has a method of calculating the perimeter and area, and the specific implementation method we can not give, only clear The specific implementation can only be given after the graphics, so we use abstract to describe these two methods. The method modified by abstract does not need to have a method body and cannot be private. Since the abstract method has no method body, if it is called by the code What should I do when I arrive? The following two restriction rules can eliminate this problem:
  
  abstract methods can only exist in abstract classes (interfaces are discussed in another article)
  
  abstract classes cannot be instantiated directly (the use of anonymous inner classes is not discussed for now)
  
  since abstract classes cannot If it is instantiated, then naturally those methods without method bodies will not be called, so how should these methods be called? We need to go through it step by step. At least for now, we can clearly get the following relationship diagram:
  
  technical picture
  
  2. The characteristics of
  
  abstract class The essence of abstract class is still a class (class), so it has all of a common class Functions, including the definition of construction methods, etc. To sum up, abstract classes have the following characteristics:
  
  abstract classes are modified by abstract
  
  . Abstract methods are allowed in abstract classes.
  
  Abstract classes cannot be instantiated directly through the constructor.
  
  Common methods can be defined in abstract classes For child class inheritance
  
  Now, we can already describe the abstract parent class in code:
  
  // Define abstract class: graphics class
  
  public abstract class Figure {
  
  // Define abstract method for calculating perimeter: getC ()
  
  public abstract double getC ();
  
  // Define abstract method for calculating area: getS ()
  
  public abstract double getS ( );
  
  // Define a non-abstract method for describing graphics: print ()
  
  public void print () {
  
  System.out.println ("This is a graphic");
  
  }
  
  }
  
  3. Natural parent class: abstract class
  
  now we already have An abstract class is defined, which also defines abstract methods. Abstract classes cannot be instantiated directly to ensure that abstract methods are not directly called. Recalling our starting point, we worked hard to create an abstract class in order to extract the more abstract common points of the two classes, then the next step is naturally inherited.
  
  An abstract class cannot be instantiated directly. It is a natural abstract class.
  
  If a class inherits an abstract class, you must override the abstract method in the parent class.
  
  If the abstract class defines a constructor, it can be called by the subclass or instantiated in the subclass object. when executed
  
  if the child still abstract class is an abstract class, an abstract method can not be rewritten, the rewriting operation is left under a subclass
  
  II rewritable
  
  Rewriting refers to the relationship formed by the methods between the child and parent classes. When the child class inherits the parent class, some methods may already exist in the parent class, so the child class instance can be directly called. In some cases, due to the differences between the parent and child classes, we want to make some modifications to existing methods. At this time, we can use rewriting to define a method in the subclass that is exactly the same as the method in the parent class, including return The value type and method signature (method name + parameter list) will constitute a rewrite at this time. In this way, the subclass instance can override the method in the parent class when calling the method. The specific process is explained in the second half.
  
  1. The difference between rewriting and overloading
  
  We learned a concept when we first came into contact with methods: overloading, which is somewhat similar to rewriting, is easy to confuse. If the knowledge point is already vague, you can enter the portal: the method design of Java programs. To sum up, rewriting and overloading have the following differences:
  
  overloading is the relationship between methods and methods in the same class
  
  rewriting is the relationship between methods and methods between the parent and child classes (between interfaces and implementation classes)
  
  constitutes overloading : the same method name, a list of different parameters, return type may be different
  
  configuration override: the name of the same method, the same parameter list, returns the same value as a corresponding type or types of sub-class
  
  permission modifier may be different between the constituting methods overloaded
  
  weight The permission modifier of the write method must be greater than the permission modifier of the rewritten method.
  
  If the role of the permission modifier is not clear, you can enter the portal: three characteristics of Java object-oriented programming-encapsulation. After clarifying the meaning of rewriting, we can finally raise the pen again and complete our previous example:
  
  // define the rectangular class
  
  public class Rectangle extends Figure {
  
  // define the constructor
  
  public Rectangle (double height, double width) {
  
  this.height = height;
  
  this.width = width;
  
  }
  
  // Define the length and width
  
  public double height;
  
  public double width;
  
  // Rewrite the calculation perimeter method
  
  @Override
  
  public double getC () {
  
  return 2 * (this.height + this.width);
  
  }
  
  // Rewrite the calculation area method
  
  @Override
  
  public double getS () {
  
  return this.height + this.width;
  
  }
  
  // Optional override
  
  @Override
  
  public void print () {
  
  System.out.println ("Rectangle");
  
  }
  
  }
  
  // define the circle class
  
  public class Circle extends Figure {
  
  // define the constructor
  
  public Circle (double radius) {
  
  this.radius = radius;
  
  }
  
  // define the radius
  
  public double radius;
  
  // Override calculation perimeter method
  
  @Override
  
  public double getC () {
  
  return 2 * Math.PI * this.radius;
  
  }
  
  // Override calculation area method
  
  @Override
  
  public double getS () {
  
  return Math. PI * Math.pow (this.radius, 2);
  
  }
  
  // Optional override
  
  @Override
  
  public void print () {
  
  System.out.println ("circle");
  
  }
  
  }
  
  2. Rule
  
  rewriting of method rewriting The
  
  rewriting of the @Override method occurs in the implementation class of the subclass or interface.
  
  The method declared by final cannot be rewritten
  
  . The method declared by static cannot be rewritten. Only static methods of the same structure can be declared, but at this time Does not constitute rewriting is
  
  limited by permission modifiers, subclasses may only be able to rewrite some of the methods in the
  
  parent class 3. Explicit call of the parent class method
  
  As you can see from the above code, after the subclass inherits the parent class, if there is an abstract method, such as rewriting, because the method in the parent class is abstract, it cannot be called. For ordinary methods, it can be selectively rewritten. Once we rewrite the method of the parent class, we can think that the method of the parent class is overwritten. In fact, such a description is inaccurate.
  
  A more standardized argument is that the method of the same name in the parent class cannot be directly called through the subclass instance, but there is still a structure of the parent class method in memory, but it is not accessible. In addition, we can also explicitly call the parent class method in the subclass, which requires the super keyword.
  
  super refers to the parent class object
  
  super can call the accessible parent class member variable
  
  super can call the accessible parent class member method
  
  super can call the accessible parent class constructor
  
  can not use super to call the abstract method in the parent class
  
  can use the super call Static methods in the parent class
  
  If we need to call the parent class method or constructor in the child class, we can modify the code as follows:
  
  // Define the abstract class: graphics class
  
  public abstract class Figure {
  
  // Define the constructor in the abstract class, Execute
  
  public Figure () {
  
  System.out.println ("Figure init");
  
  }
  
  // define the abstract method of calculating the perimeter when the subclass instance is created : getC ()
  
  public abstract double getC ();
  
  // define the calculated area Abstract method: getS ()
  
  public abstract double getS ();
  
  // Define a non-abstract method for describing graphics: print ()
  
  public void print () {
  
  System.out.println ("This is a graphic");
  
  }
  
  }
  
  // define the rectangular class
  
  public class Rectangle extends Figure {
  
  // define the construction device
  
  public the Rectangle (Double height, Double width) {
  
  Super (); // will call the default constructor with no arguments, the code may be omitted
  
  this.height = height;
  
  this.width = width;
  
  }
  
  // width and a height
  
  public double height ;
  
  public double width;
  
  // Override calculation perimeter method
  
  @Override
  
  public double getC () {
  
  return 2 * (this.height + this.width);
  
  }
  
  // Override calculation area method
  
  @Override
  
  public double getS () {
  
  return this.height + this.width;
  
  }
  
  // optional override
  
  @Override
  
  public void print () {
  
  super.print (); // call the parent class method
  
  System.out.println ("rectangle");
  
  }
  
  }
  
  // define the circle class
  
  public class Circle extends Figure {
  
  // define the constructor
  
  public Circle (double radius) {
  
  super (); // Will call the default no-parameter construction, the code can be omitted
  
  this.radius = radius;
  
  }
  
  // Define the radius
  
  public double radius;
  
  // Rewrite the calculation perimeter method
  
  @Override
  
  public double getC () {
  
  return 2 * Math.PI * this.radius;
  
  }
  
  // Rewrite the calculation area method
  
  @Override
  
  public double getS () {
  
  return Math.PI * Math.pow (this.radius, 2);
  
  }
  
  / / Optional override
  
  @Override
  
  public void print () {
  
  super.print (); // Call the parent class method
  
  System.out.println ("circle");
  
  }
  
  }
  
  Three, the parent class reference points to the child class object
  
  After the concept mentioned above is digested, let ’s take a look at the child parent class The form of object instantiation and the execution effect of the method.
  
  1. The parent class reference points to the parent class object.
  
  If the parent class is an abstract class, you cannot use the new plus constructor method to instantiate on the right side of the equal sign. If you must get the parent class instance, you must use the anonymous inner class. Usage, not discussed here.
  
  If the parent class is a normal class, then when we initialize, the left side of the equal sign is the parent type reference, and the right side of the equal sign is the parent type object (instance). At this time, there is no difference between us and creating a class object. , There is no need to think that he is the parent of a certain class, because at this time he will not have a relationship with any subclass, just a normal class that inherits the Object class by default, just use it normally, and the content can be called Is defined in the parent class.
  
  2. The subclass reference points to the subclass object
  
  When the subclass is instantiated, the parent class is inherited in the definition of the subclass, so when creating the subclass object, the parent class object will be created first. When making a call, according to the permission modifier, you can call out the attributes and methods that can be accessed in the subclass and the parent class.
  
  public class Test {
  
  public static void main (String [] args) {
  
  Rectangle rectangle = new Rectangle (5,10);
  
  // call the method defined in Rectangle, subject to subclass rewriting
  
  rectangle.print ();
  
  System.out.println (rectangle.getC ()); // Get the rectangular perimeter
  
  System.out.println (rectangle.getS ()); // Get the rectangular area
  
  Circle circle = new Circle (5);
  
  // Call Circle The method defined in is subject to subclass rewriting
  
  circle.print ();
  
  System.out.println (circle.getC ()); // Get the circular perimeter
  
  System.out.println (circle.getS ()) ; // Get the circular area
  
  }
  
  }
  
  3. The relationship between references and objects
  
  When we first started learning programming, we were exposed to basic data types, which can be directly declared with keywords, used after defining variable assignments, and do not need to use new Keywords. For the relationship between references and objects, please refer to the previous article to review: the basic operating unit in Java-classes and objects. What we want to explain here is how the reference part on the left side of the equal sign is related to the part on the right side of the equal sign at the program execution level.
  
  Unlike basic data types, various properties and methods can be defined in the class, and objects need to be created before use. The part on the left side of the equal sign is still a type declaration. Although it is null by default when it is not assigned, it will also be stored in the stack when the program is compiled and run, and the corresponding structural information is recorded. The object he points to must be It is a type compatible with it.
  
  Class declaration references are stored on the stack, and the instantiated objects are stored on the heap.
  
  In the code writing stage, the content that can be called out is based on the type on the left side of the equal sign.
  
  In the program running stage, the specific execution effect is based on the instance on the right side of the equal sign.
  
  The following figure is a schematic diagram of the relationship between references and instances in memory. The distribution of Java objects in memory will be explained in another article:
  
  Technical picture
  
  4. The parent class reference points to the child class object. After
  
  understanding the relationship between references and objects, There is a question, what if the declared type on the left side of the equal sign is inconsistent with the instance type on the right side of the equal sign? If we want to ensure that the program can be compiled and executed smoothly, we must ensure that the types on both sides of the equal sign are compatible. Two completely unrelated classes cannot appear on the left and right sides of the equal sign. Even if you can use forced type conversion through compilation, an exception will still be thrown at runtime.
  
  So we thought about whether it is possible to be compatible with child and parent classes? There will be two cases: the subclass reference points to the parent class object, and the parent class reference points to the subclass object. Let's discuss them one by one below.
  
  Why does the subclass reference point to the parent class object? The
  
  subclass reference point to the parent class object refers to: the left side of the equal sign is the declaration definition of the subtype, and the right side of the equal sign is the instance of the parent type. First, the conclusion is that such usage does not exist, and we analyze the reasons from two aspects.
  
  Is the first aspect logical? In other words, will there be a need for the Java language to provide developers with such a usage? Obviously no, the purpose of defining the subclass is to extend the functionality of the parent class. As a result, we are now using an old, poorly functioning parent class instance (on the right side of the equal sign) to satisfy the powerful and functional The need for a more powerful subclass declaration (on the left side of the equal sign) is obviously unreasonable.
  
  On the other hand, can it be done while the program is running? If we really write the relevant code, we will be asked to add a forced conversion statement, otherwise it will fail to compile, and even if it passes, it will prompt that the type conversion cannot be performed at runtime. This is equivalent to forcibly converting an old machine that can only call and send text messages into a smart machine that can install various apps, which is obviously impossible.
  
  What does it mean for a parent class reference to point to a child class object
  
  The parent class reference points to the child class object: the left side of the equal sign is the definition of the parent type, and the right side of the equal sign is the instance of the sub type. This situation is often used, similar to: the interface points to the implementation class. So, how should this usage be explained, and why should there be such usage?
  
  First of all, let ’s understand what this means, if: the parent class is graphics, and the child class is rectangle and circle. This is like I declared a graphics object. At this time, we know that the methods defined in the graphics class can be called. Since the graphics class is an abstract class, it cannot be instantiated directly. We can only use his two subclasses to try Try it.
  
  public class Test {
  
  public static void main (String [] args) {
  
  // figure1 points to the Rectangle instance
  
  Figure figure1 = new Rectangle (5,10);
  
  System.out.println (figure1.getC ()); // get the rectangular perimeter Long
  
  System.out.println (figure1.getS ()); // Get the rectangular area
  
  // figure2 points to the Circle instance
  
  Figure figure2 = new Circle (5);
  
  System.out.println (figure2.getC ()); // get Circular perimeter
  
  System.out.println (figure2.getS ()); // Get the circular area
  
  }
  
  }
  
  From the above results, it seems that there is no difference between the execution effect of the subclass reference pointing to the subclass object? However, it should be noted that the reference of the parent class is used at this time. The difference is that if we define unique content in the subclass, it cannot be called. It has been explained above that the running effect is based on the instance on the right side of the equal sign, so it is not difficult to understand that the result is the same as the directly created subclass instance.
  
  It is important to explain the meaning of it: using the Figure statement, it means that I now only know that it is a figure and I know which methods can be executed. If I tell it to be a rectangle, then I can calculate the circumference and area of ​​the rectangle; if It is a circle, then the circumference and area of ​​the circle can be calculated. We can also describe it this way: this figure is a rectangle or this figure is a circle.
  
  If we explain from the perspective of program operation, we already know that the subclass object will instantiate the parent class object when it is instantiated, and if the subclass overrides the parent class method, the parent class method will be hidden. If we use a parent class reference to point to a subclass object, this is equivalent to an object instance is very powerful, but we can only enable part of the function, but there is an advantage that the same instruction, different subclass objects can be executed, And there will be differences. This is equivalent to an elderly machine with only the functions of making calls and sending text messages. Both Xiaomi phones and Meizu phones are upgraded and expanded smart phones. Of course, they retain the most basic communication functions of the phone, so it is no problem to use it.
  
  Fourth, polymorphism After
  
  learning the above content, in fact, you have mastered the usage of polymorphism, now let's summarize it clearly.
  
  1. What is polymorphism?
  
  Polymorphism refers to the same parent class, or the same interface, issued a same instruction (called the same method), because the specific implementation of the instance (subclass object or implementation class object) is different , And there are different forms of performance (execution effect).
  
  Just like the graphics in the above example, it is an abstract class itself, in which there are some abstract methods, and the specific execution can be completed by subclass objects. For the abstract method of the abstract class, because the subclass must be rewritten, the subclass to execute the abstract method of the parent class is necessarily a manifestation of polymorphism, for other cases it does not necessarily constitute polymorphism, so the following three necessary condition.
  
  2. Necessary conditions for polymorphism
  
  There is a subclass inheritance relationship
  
  Method for subclass to rewrite parent class
  
  Parent class reference points to subclass object
  
  Only when these three conditions are met can it be polymorphic, which is the first three points of this article. The reason for the space.
  
  3. The advantages of polymorphism The
  
  use of polymorphism has many advantages, especially when an abstract class has multiple subclasses, or an interface has multiple abstract classes, it will be very flexible when passing parameters, only need in the method Define a parent type as a declaration, the parameters passed in can be the parent type itself, or it can be any corresponding subtype object. Therefore, the advantages of polymorphism can be summarized as follows:
  
  reduce coupling: only need to associate with the parent type
  
  maintainability (inheritance guarantee): only need to add or modify a certain subtype, will not affect the
  
  scalability of other classes (Polymorphism guarantee): Using subclasses, you can quickly expand existing functions
  
  flexibility
  
  interface

Guess you like

Origin www.cnblogs.com/javabk6/p/12717262.html