for object-oriented programming languages, Polymorphism is the third most basic feature , the first two types are data abstraction and inheritance.
"Polymorphism" (polymorphism) separates interfaces from specific implementation details from another perspective, i.e. the separation of "what" and "how to Do" two modules. Using the concept of polymorphism, the organization of code and readability can be improved. In addition, you can create "easy-to-extend" programs. It's easy to "grow" both during project creation and when new features need to be added .
1. back to styling
Use an object as its own type, or as an object of its underlying type. Made
The behavior of an object handle, which is used as the underlying type handle, is called "upstream"-because the inheritance tree is drawn as the base class at the top.
Package c07;class note { private int value; private note ( Int val) { value = val; } public static final note middlec = new note (0), csharp = new note (1), Cflat = new note (2);} Class instrument { public void play (note n) { System.out.println ("Instrument.play ()"); }}// wind objects are instruments// because they have the same interface:class Wind extends instrument { // redefine interface method: public void Play (Note n) { system.out.println ("Wind.play ()"); }}public class Music { public static void tune (instrument i) { // ... &nBsp;i.play (Note.middlec); } public static void main (String[] args) { wind flute = new wind (); tune (flute); // Upcasting }}
Wherein, the method Music.tune () receives a instrument handle , and also receives Everything derived from the instrument. This can happen when a wind handle is passed to tune () .
Why go back to styling
This app may seem a little strange. Why should everyone deliberately forget the type of an object? When it comes to modelling, this confusion can arise. And if tune () simply gets a wind handle and uses it as its own argument, it seems much simpler and more intuitive. But note that if you do that, you need to Write a new tune ()for each type of instrument in the system.
Let's say that the two types of instrument , stringed (string) and Brass (copper tube), are added to the preceding inference. (musical instrument):
... public class Music2 {public static void tune (Wind2 i) {i.play (Note2.middlec); } public static void tune (Stringed2 i) {i.play (Note2.middlec); } public static void tune (Brass2 i) {i.play (Note2.middlec); } public static void Main (string[] args) {Wind2 flute = new Wind2 (); Stringed2 violin = new Stringed2 (); Brass2 Frenchhorn = new Brass2 (); Tune (flute); No upcasting Tune (violin); Tune (Frenchhorn); }}
This will add a lot of code, the type of the entire operation process is extremely difficult to manage, there is a danger of runaway.
2. In- depth understanding
The difficulty of Music.java can be realized by running the program. The output is wind.play (). This, of course, is the output we want, but it does not seem to be willing to act as we wish.
It receives the instrument handle . So in this case, how does the compiler know that the instrument handle is pointing to a wind, not a Brass or where's stringed ? The compiler has no way of knowing. In order to understand this problem, it is necessary to explore the topic of "binding".
2.1 binding of method calls
Connecting a method call to the same method body is called a binding.
The workaround is "late binding", which means that the binding takes place during run time, based on the type of the object. Late binding is also called "Dynamic binding" or "run-time binding."
all methods bound in Java use late-binding techniques unless a method has been declared final. This means that we usually don't have to decide whether late binding should occur-it happens automatically.
Why declare a method to be final ? As indicated in final use, it prevents others from overwriting that method. But perhaps more importantly, it can effectively "turn off" dynamic binding, or tell the compiler that it does not need to be dynamically bound. This allows the compiler to generate more efficient code for final method calls.
2.2 produce the right behavior
In object-oriented program design, there is a classic "shape" example. Because it is easy to visualize, it is often used to illustrate problems.
Theshape example has a base class named shape, plus anumber of derivative types:circle(circle),Square(square) , Triangle(triangles) and so on.
650) this.width=650; "src=" Http://s4.51cto.com/wyfs02/M02/78/36/wKiom1Z35Cagkq9dAACVB97hsAE580.png "title=" capture. PNG "alt=" Wkiom1z35cagkq9daacvb97hsae580.png "/>
The following statement can be used to simply show:
Shape s = new Circle ();
2.3 Scalability
Now, let's still return to the instrument (instrument) example. Because of polymorphism, you can add as many new types as you want to your system without changing the tune () method. In a well-designed OOP program, most or all of our methods follow the model of tune () and only communicate with the underlying class interface. We say that such a program is "extensibility" because new data types can be inherited from a common base class to add functionality. If it is to accommodate the requirements of the new class, then the method of manipulating the underlying class interface does not need to be changed at all .
For a musical instrument example, suppose we add more methods to the base class, and a series of new classes, the following are:
650) this.width=650; "src=" Http://s5.51cto.com/wyfs02/M01/78/36/wKiom1Z35FqQZZprAACUKa2OhdQ653.png "title=" capture. png "alt=" Wkiom1z35fqqzzpraacuka2ohdq653.png "/>
All of these new classes can work with the old class-tune () without any adjustment to tune () . Even if tune () is in a separate file, and the new method is added to the instrument interface,tune () can work correctly. No recompilation is required. The following procedure is a specific implementation of the above:
Import java.util.*;class instrument3 { public void play () { system.out.println ("Instrument3.play ()"); } public string what () { return "Instrument3"; } public void adjust () {} } Class wind3 extends instrument3 { public void play () { system.out.println ("Wind3.play ()"); } public string what () { return "Wind3"; } public void adjust () {}}class Percussion3 Extends instrument3 { public void play () { system.out.println (" Percussion3.play () "); } public string what () { return " Percussion3 "; } public void adjust () {}}class Stringed3 extends Instrument3 { publIc void play () { system.out.println ("Stringed3.play ()"); } Public string what () { return "Stringed3"; } public void Adjust () {}}class brass3 extends wind3 { public void play () { system.out.println ("Brass3.play ()"); } public void adjust () { system.out.println ("Brass3.adjust ()"); }}class woodwind3 extends Wind3 { public void play () { system.out.println ("Woodwind3.play ()"); } public string what () { return "Woodwind3"; }}public &NBSP;CLASS&NBSP;MUSIC3&NBSP;{&NBSP;&NBSP;//&NBSP;DOESN ' T care about type, so new types // added to the system still work right: Static void tune (INstrument3 i) { // ... i.play (); } static void tuneall (instrument3[] e) { for (int i = 0; i < e.length; i++) tune (E[i]); } public static void main ( String[] args) { Instrument3[] orchestra = new Instrument3[5]; int i = 0; // Upcasting during addition to the Array: orchestra[i++] = new wind3 (); orchestra[i++] = new Percussion3 (); orchestra[i++] = new stringed3 (); orchestra[i++] = &NBSP;NEW&NBSP;BRASS3 (); orchestra[i++] = new woodwind3 (); tuneAll ( Orchestra); }}
The new method is what () and adjust (). The former returns a String handle and returns a description of that class, which allows us to adjust each instrument.
In main () , when we place something in the Instrument3 Array, we automatically go back to the Instrument3.
As you can see, all other code around the tune () method changes whilethetune () method is unaffected by them.
3. Overlay and Overload
"Overload" means that the same thing has multiple meanings in different places, while "overlay" means that it
There is only one meaning, but the original meaning is completely replaced by the later meanings.
Multi-shape Sex